Java调用AWS S3 Put Object偶发Invalid SSL master secret错误求助
我的Java代码通过「服务器 -> AWS CloudFront -> AWS S3」的路径向S3存储桶执行Put操作时,出现偶发性错误。已确认IAM访问密钥处于激活状态,CloudFront有时能正常转发请求,有时返回以下错误:
执行Put操作的Java代码:
s3.putObject(new PutObjectRequest(IMAGES_S3_BUCKET_NAME, filename, resizedImageFile).withCannedAcl(CannedAccessControlList.PublicRead));
服务器返回的错误日志:
WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by com.amazonaws.http.conn.ssl.SdkTLSSocketFactory WARNING: Please consider reporting this to the maintainers of com.amazonaws.http.conn.ssl.SdkTLSSocketFactory WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release 2024-04-27 01:55:03.037 ERROR 1138 --- [nio-8080-exec-7] o.s.b.w.servlet.support.ErrorPageFilter : Forwarding to error page from request [/imageUpload] due to exception [Invalid SSL master secret] java.lang.SecurityException: Invalid SSL master secret at com.amazonaws.http.conn.ssl.SdkTLSSocketFactory.verifyMasterSecret(SdkTLSSocketFactory.java:134) ~[aws-java-sdk-core-1.9.6.jar:na] at com.amazonaws.http.conn.ssl.SdkTLSSocketFactory.connectSocket(SdkTLSSocketFactory.java:112) ~[aws-java-sdk-core-1.9.6.jar:na] at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java:180) ~[httpclient-4.5.13.jar:4.5.13] at org.apache.http.impl.conn.ManagedClientConnectionImpl.open(ManagedClientConnectionImpl.java:326) ~[httpclient-4.5.13.jar:4.5.13] at org.apache.http.impl.client.DefaultRequestDirector.tryConnect(DefaultRequestDirector.java:605) ~[httpclient-4.5.13.jar:4.5.13]
需要修改哪些配置或代码,才能让Put命令100%执行成功?
升级AWS Java SDK版本:当前使用的
aws-java-sdk-core-1.9.6.jar版本过于陈旧,其SdkTLSSocketFactory存在非法反射逻辑,在高版本JDK(如Java 11+)中会触发SSL连接异常。建议直接升级到AWS SDK for Java v1的最新稳定版,或迁移至更现代的AWS SDK for Java v2(推荐),新版本已修复此类SSL相关兼容性问题。添加重试机制:针对偶发性连接错误,通过AWS SDK的重试策略自动恢复。示例配置:
ClientConfiguration clientConfig = new ClientConfiguration(); // 使用默认重试策略,可根据需求调整重试次数、间隔等 clientConfig.setRetryPolicy(PredefinedRetryPolicies.DEFAULT_RETRY_POLICY); AmazonS3 s3 = AmazonS3ClientBuilder.standard() .withClientConfiguration(clientConfig) .build();
调整CloudFront配置:
- 确保CloudFront源配置的SSL协议版本为
TLS 1.2及以上,避免与服务器JDK的SSL协议不匹配导致握手失败; - 检查CloudFront对应的缓存行为,确认已允许
PUT请求(默认缓存行为通常仅开放GET/HEAD等读操作)。
- 确保CloudFront源配置的SSL协议版本为
临时缓解反射警告(不推荐长期使用):若暂时无法升级SDK,可在JVM启动参数中添加
--add-opens java.base/sun.security.ssl=ALL-UNNAMED,允许SDK的反射访问。但该方案仅为临时 workaround,未来JDK版本会彻底禁止此类非法反射。验证JDK兼容性:确保使用的JDK版本与AWS SDK兼容。若坚持使用旧版SDK,建议切换至Java 8(需注意Java 8的官方支持期限);若使用Java 11+,必须升级SDK版本。
内容的提问来源于stack exchange,提问作者Gene

