Java 使用base64编码写入文件时的AES解密

Java 使用base64编码写入文件时的AES解密,java,encryption,cryptography,base64,aes,Java,Encryption,Cryptography,Base64,Aes,我正在实施以下步骤: Bob用AES加密消息 Bob将加密编码为base64字符串 Bob将字符串写入文件 艾丽斯读文件 Alice将字符串转换为字节 爱丽丝解密了这个消息 然而,我在最后一步失败了 以下是加密: public void sendHelloWorld() { String msg = "hello world!"; try { SecretKeySpec AesKeySpec = new SecretKeySpec(aesKey

我正在实施以下步骤:

  • Bob用AES加密消息
  • Bob将加密编码为base64字符串
  • Bob将字符串写入文件
  • 艾丽斯读文件
  • Alice将字符串转换为字节
  • 爱丽丝解密了这个消息
  • 然而,我在最后一步失败了

    以下是加密:

    public void sendHelloWorld() {
        String msg = "hello world!";
        try {
            SecretKeySpec AesKeySpec = new SecretKeySpec(aesKeyBytes, "AES");
            Cipher c = Cipher.getInstance("AES/CBC/PKCS5Padding");
            c.init(Cipher.ENCRYPT_MODE, AesKeySpec);
            aesEncryptedHello = c.doFinal(msg.getBytes());
        } catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        String s = new String(aesEncryptedHello, StandardCharsets.UTF_8);
        System.out.println("Message = " + s);
        sendMessage(Base64.getEncoder().encodeToString(aesEncryptedHello));
    }
    
    下面是解密:

    public void decryptAESMessage(byte[] encryptedMessage) {
        try {
            String s = new String(encryptedMessage, StandardCharsets.UTF_8);
            System.out.println("Message = " + s);
            SecretKeySpec AesKeySpec = new SecretKeySpec(bobAesKey, "AES");
            Cipher c = Cipher.getInstance("AES/ECB/PKCS5Padding");
            c.init(Cipher.DECRYPT_MODE, AesKeySpec);
            byte[] aesMessage = c.doFinal(encryptedMessage);
            String message = new String(aesMessage, StandardCharsets.UTF_8);
            System.out.println("Message is " + message);
        } catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        
    }
    
    以下是写入文件:

    public void sendMessage(String msg) {
        try {
            
            FileWriter myWriter = new FileWriter(<myredactedfilepath>);
            myWriter.write(msg);
            myWriter.close();
        } catch (IOException e) {
            System.out.println("An error occurred.");}
    }
    

    我在两端打印密钥和加密消息,并且它们匹配。

    在加密部分,您使用了
    AES/CBC/PKCS5Padding
    ,这是带有PKCS 5的CBC操作模式-实际上,是PKCS 7-缺少IV。CBC模式需要和IV,这至少应该是随机的。可以用

    SecureRandom-SecureRandom=new-SecureRandom();
    byte[]iv=新字节[cipher.getBlockSize()];
    随机。下一个字节(iv);
    IvParameterSpec ivParams=新的IvParameterSpec(iv);
    
    在解密部分,您使用了
    AES/ECB/PKCS5Padding
    。通常两者必须匹配。在静脉注射时同时使用ECB(请不要)或CBC

    IV通常附加在密文的开头。在解密过程中解析并使用它

    另外,在解密内部进行base64解码。这将使您的模式更加健壮

    最后注意:如果没有具体原因,请选择AES-GCM,它不仅可以提供机密性,还可以提供完整性和身份验证。如果您需要坚持CBC,您还需要使用HMAC来实现完整性和身份验证


    以及完整的代码示例;请参阅

    加密
    AES/CBC/pkcs5p添加
    和IV缺失。解密
    AES/ECB/PKCS5Padding
    将ECB(请不要)或CBC与IV一起提供并附加到密文开头。在解密过程中解析并使用它。这个网站上有很多这样的例子。@kelalaka Noooooo,真不敢相信我花了这么长时间却没有注意到。谢谢你这里可能还有一些其他的错误,我也没有看到deeoer…不,就是这样,它现在工作正常在这种情况下,你可以写一个答案来回答你的问题。
    alice.decryptAESMessage(Base64.getDecoder().decode(alice.readEncryptedMessage()));