使用AES

时间:2016-06-02 13:13:32

标签: java amazon-web-services amazon-s3 aes

怎么办?

1.上传到S3时加密文件

  1. 从S3下载时解密文件
  2. 我做了什么?

    • 书面代码,从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对象)

3 个答案:

答案 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)

您似乎陷入了需要进一步调试和测试的问题。

让我们来看看以下情景:

基本上传和下载:

  1. 创建一个简单的文本文件(例如Lorem Ipsum的几段)
  2. 测量文件大小,并将其上传到S3。
  3. 从S3下载文件,检查文件大小。
  4. 有区别吗?如果文件在repo中完成,请通过S3Browser等工具进行检查,以检查上传是否失败,或下载是否失败。
  5. 基本编码:

    1. 重试基本上传和下载,但这次使用base64对文件进行编码。
    2. 有区别吗?检查编码和解码是否在没有S3的情况下工作。
    3. 它没有S3,但没有?可能与您向S3发送数据的方式有关。通过Wireshark或某些网络嗅探器检查实际发送给S3的数据。
    4. AES加密

      1. 现在尝试使用AES加密基本编码
      2. 完成上述步骤后仍然卡住了。请告诉我们您的发现,以便我们更好地为您提供帮助。因此,还要发布执行按预期工作的代码片段。