AWS S3 Java SDK-通过销售合作伙伴(SP)API url流下载加密的GetObject
我最近开始使用SellingPartner(SP),我有点困惑他们如何向我们提供S3报告供下载 当我从SP API获取报告文档时,我得到以下返回(省略): 如果我直接在我的浏览器中复制/粘贴AWS S3 Java SDK-通过销售合作伙伴(SP)API url流下载加密的GetObject,java,amazon-web-services,amazon-s3,encryption,Java,Amazon Web Services,Amazon S3,Encryption,我最近开始使用SellingPartner(SP),我有点困惑他们如何向我们提供S3报告供下载 当我从SP API获取报告文档时,我得到以下返回(省略): 如果我直接在我的浏览器中复制/粘贴payload.url,它会下载一个加密的文档,看起来不错(但我无法解密,最后是一个片段) 我正在尝试使用AWS S3 Java SDK进行下载,我不断得到software.amazon.awssdk.services.S3.model.S3异常:访问被拒绝 我有一段话: public String getR
payload.url
,它会下载一个加密的文档,看起来不错(但我无法解密,最后是一个片段)
我正在尝试使用AWS S3 Java SDK进行下载,我不断得到software.amazon.awssdk.services.S3.model.S3异常:访问被拒绝
我有一段话:
public String getReportFile(String reportDocumentId) throws IOException {
GetReportDocumentResponse response = getReport(reportDocumentId);
ReportDocumentEncryptionDetails encryptionDetails = response.getPayload().getEncryptionDetails();
GetObjectRequest request =
GetObjectRequest.builder()
.key(reportDocumentId)
.bucket("tortuga-prod-na") //hardcoding here, thats the bucket on the URL, right?
.sseCustomerAlgorithm(encryptionDetails.getStandard())
.sseCustomerKey(encryptionDetails.getKey())
// .sseCustomerKeyMD5() should I apply it? Is that the Initialization Vector field?
.build();
//I tried both without Credentials, and using accessKey and secretKey from my personal account, not sure if should be another one related to the URL, what should I use for credentials if the URL works fine in my browser?
StaticCredentialsProvider credentialsProvider =
StaticCredentialsProvider.create(AwsBasicCredentials.create(accessKey, secretKey));
BufferedReader br =
new BufferedReader(
new InputStreamReader(
S3Client.builder()
.credentialsProvider(credentialsProvider)
.region(Region.US_EAST_1)
.build()
.getObject(request)));
我的最终目标是分块下载这个文件(因为它可能超过500mb),并一次处理几百行。如果是加密的,那可能吗?我想下载它已经解密,并能够处理它在块
我想知道如何使用S3Client发出相同的请求,比如来自JSON的URL。我们有没有办法在S3Client上粘贴一个URL,包括加密设置并打电话
关于从浏览器下载的文件,我尝试通过以下方式对其进行解密:
byte[] bytes = FileUtils.readFileToByteArray(new File("encrypted_file"));
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
SecretKeySpec secretKey = new SecretKeySpec(Base64.getDecoder().decode(<payload.encryptionDetails.key String value>), "AES");
cipher.init(Cipher.DECRYPT_MODE, secretKey);
System.out.println(new String(cipher.doFinal(bytes)));
byte[]bytes=FileUtils.readFileToByteArray(新文件(“加密的_文件”);
Cipher Cipher=Cipher.getInstance(“AES/ECB/PKCS5PADDING”);
SecretKeySpec secretKey=新的SecretKeySpec(Base64.getDecoder().decode(),“AES”);
cipher.init(cipher.DECRYPT_模式,secretKey);
System.out.println(新字符串(cipher.doFinal(字节));
这会引发异常:
线程“main”javax.crypto.BadPaddingException中的异常:给定的最后一个块没有正确填充。如果在解密过程中使用了坏密钥,则可能会出现此类问题。
提前谢谢
如果我直接在浏览器中复制/粘贴payload.url,它会下载一个加密的文档,看起来很好(但我无法解密,最后是一个片段)
这意味着该对象未使用SSE-C,否则您将无法下载它。似乎内容是在客户端加密的(在S3API之外),加密的内容是作为普通对象上传的。因此,请在上传内容的代码中检查加密参数
如果可以直接从浏览器下载对象,则只需将内容作为普通对象下载即可
注意:正确使用
关于从浏览器下载的文件,我试着这样解密它
无论您在哪里获得此代码,请不要使用它。仅使用AES/ECB/PKCS5P添加模式是不安全的
使用IV(initializationVector)意味着使用不同的。您必须找出加密内容的代码或服务中的内容
private static final String SYMMETRIC_KEY_ALG = "AES";
// find out the correct value, could be AES/CBC/PKCS5Padding
private static final String SYMMETRIC_CIPHER_NAME = "???";
IvParameterSpec ivParamSpec = new IvParameterSpec(encryptionParams.getIv());
SecretKey symmetricKey = new SecretKeySpec(encryptionParams.getKey(), SYMMETRIC_KEY_ALG);
Cipher cipher = Cipher.getInstance(SYMMETRIC_CIPHER_NAME);
cipher.init(Cipher.DECRYPT_MODE, symmetricKey, ivParamSpec);
byte[] decrypted = cipher.doFinal(encryptionParams.getCiphertext());
但是,您确实需要了解内容是如何加密的。有可能使用aes gcm模式,然后部分密文可以是身份验证哈希。所以在这里,你不应该做假设,找到真实的数据
private static final String SYMMETRIC_KEY_ALG = "AES";
// find out the correct value, could be AES/CBC/PKCS5Padding
private static final String SYMMETRIC_CIPHER_NAME = "???";
IvParameterSpec ivParamSpec = new IvParameterSpec(encryptionParams.getIv());
SecretKey symmetricKey = new SecretKeySpec(encryptionParams.getKey(), SYMMETRIC_KEY_ALG);
Cipher cipher = Cipher.getInstance(SYMMETRIC_CIPHER_NAME);
cipher.init(Cipher.DECRYPT_MODE, symmetricKey, ivParamSpec);
byte[] decrypted = cipher.doFinal(encryptionParams.getCiphertext());