怎么办?
1.上传到S3时加密文件
我做了什么?
javax.crypto.IllegalBlockSizeException:输入长度必须为多个 用填充密码解密时的16;
从上面的异常我明白,我想要解密的数组大小有问题。
我已检查过加密后字节数组的大小和字节大小 从S3对象得到的数组是不同的,但不知道如何处理 此
加密和上传代码
public void upload(FileItem itemFile , String keyName)
{
try{
InputStream is = itemFile.getInputStream();
byte[] plain = IOUtils.toByteArray(is);
String plaintxt = new String(plain, StandardCharsets.UTF_8);
final String base64Key = "ABEiM0RVZneImaq7zN3u/w==";
final String base64Iv = "AAECAwQFBgcICQoLDA0ODw==";
final byte[] keyBytes = DatatypeConverter.parseBase64Binary(base64Key);
final byte[] ivBytes = DatatypeConverter.parseBase64Binary(base64Iv);
byte[] encryptedBytes = AES.encrypt(keyBytes, ivBytes, plaintxt.getBytes());
System.out.println("Length of encrypted bytes "+ encryptedBytes.length);
s3client.putObject(new PutObjectRequest(StorageServerProperties.S3_BUCKET_NAME_Audit_Server, keyName, new ByteArrayInputStream(encryptedBytes), om));
s3client.setObjectAcl(StorageServerProperties.S3_BUCKET_NAME_Audit_Server, keyName, CannedAccessControlList.PublicRead);
}catch(Exception ex)
{
ex.printStackTrace()'
}
}
解密代码
public void decrypt(String userName, String fileName)
AmazonS3 s3client = new AmazonS3Client(StorageServerProperties.credentials);
S3Object file = s3client.getObject(StorageServerProperties.S3_BUCKET_NAME_Storage_Server,userName+"/"+filename );
byte[] cipherBytes = IOUtils.toByteArray(file.getObjectContent());
String cipher = new String(cipherBytes, StandardCharsets.UTF_8);
byte[] cipherBytes1 = cipher.getBytes();
System.out.println("Length in decryption 1 "+ cipherBytes.length);
System.out.println("Length in decryption 1 "+ cipherBytes1.length);
final String base64Key = "ABEiM0RVZneImaq7zN3u/w==";
final String base64Iv = "AAECAwQFBgcICQoLDA0ODw==";
final byte[] keyBytes = DatatypeConverter.parseBase64Binary(base64Key);
final byte[] ivBytes = DatatypeConverter.parseBase64Binary(base64Iv);
byte[] plainBytes = null;
try {
plainBytes = AES.decrypt(keyBytes, ivBytes, cipher.getBytes());
} catch (InvalidKeyException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchAlgorithmException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvalidAlgorithmParameterException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalBlockSizeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (BadPaddingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
我知道AWS提供了使用api加密和解密文件的选项,但我不想使用他们的api。
对于AES加密和解密我正在使用
AES / CBC / PKCS5Padding
修改
当我加密时,数据大小为22320字节。 当我从S3存储桶中获取S3对象并将其转换为byte []时,其大小为22314.即丢失了6个字节。
我可以在本地机器上加密和解密同一个文件。(即没有s3对象)
答案 0 :(得分:0)
对于解密,您可以编写如下代码:
/* Decrypt the message, given derived key and initialization vector. */
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(iv));
String plaintext = new String(cipher.doFinal(ciphertext), "UTF-8");
System.out.println(plaintext);
对于可运行的示例,您可以浏览this link.
答案 1 :(得分:0)
消息非常明确:“javax.crypto.IllegalBlockSizeException:输入长度必须是16的倍数,当使用填充密码进行解密时”。
AES加密是基于块的,对于诸如CBC之类的模式,数据必须是块大小的倍数(AES为16-byted)。如果输入数据不是块大小的倍数,则必须填充,典型的选项是PKCS#7(néePKCS#5)。检查填充是否为默认选项,因为未指定填充。
检查发送到服务器并从服务器返回的长度是否与块长度的倍数相同。
您可以使用Cryptomathic在线AES calculator检查加密/解密。
答案 2 :(得分:0)
您似乎陷入了需要进一步调试和测试的问题。
让我们来看看以下情景:
基本上传和下载:
基本编码:
AES加密
完成上述步骤后仍然卡住了。请告诉我们您的发现,以便我们更好地为您提供帮助。因此,还要发布执行按预期工作的代码片段。