【问题标题】:Having trouble porting this from vb.net to Java AES encryption将其从 vb.net 移植到 Java AES 加密时遇到问题
【发布时间】:2016-05-25 18:04:46
【问题描述】:

这是在 .net 中编码并在 Java 中解码的完整工作示例,反之亦然

    Private Function Decrypt(cipherText As String) As String
dim _encryptionkey as string = "kmjfds(#1231SDSA()#rt32geswfkjFJDSKFJDSFd"
        Dim cipherBytes As Byte() = Convert.FromBase64String(cipherText)
        Using encryptor As Aes = Aes.Create()
            Dim pdb As New Rfc2898DeriveBytes(_EncryptionKey, New Byte() {&H49, &H76, &H61, &H6E, &H20, &H4D, &H65, &H64, &H76, &H65, &H64, &H65, _
             &H76})
            encryptor.Key = pdb.GetBytes(32)
            encryptor.IV = pdb.GetBytes(16)
            Using ms As New MemoryStream()
                Using cs As New CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write)
                    cs.Write(cipherBytes, 0, cipherBytes.Length)
                    cs.Close()
                End Using
                cipherText = Encoding.Unicode.GetString(ms.ToArray())
            End Using
        End Using
        Return cipherText
    End Function

这是 Java 的等价物。感谢大家的帮助!确保在 Java 的安全文件夹中也安装 JCE 策略。

String myData = "kgxCSfBSw5BRxmjgc4qYhwN12dxG0dyf=";
        byte[] salt = new byte[] {0x49, 0x76, 0x61, 0x6E, 0x20, 0x4D, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76};
        String pw  = "kmjfds(#1231SDSA()#rt32geswfkjFJDSKFJDSFd";

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        PBEKeySpec pbeKeySpec = new PBEKeySpec(pw.toCharArray(), salt, 1000, 384);
        Key secretKey = factory.generateSecret(pbeKeySpec);
        byte[] key = new byte[32];
        byte[] iv = new byte[16];
        System.arraycopy(secretKey.getEncoded(), 0, key, 0, 32);
        System.arraycopy(secretKey.getEncoded(), 32, iv, 0, 16);


        SecretKeySpec secretSpec = new SecretKeySpec(key, "AES");
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        Cipher cipher1 = Cipher.getInstance("AES/CBC/PKCS5Padding");

        try {
            cipher.init(Cipher.DECRYPT_MODE,secretSpec,ivSpec);
            cipher1.init(Cipher.ENCRYPT_MODE,secretSpec,ivSpec);
        } catch (InvalidKeyException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvalidAlgorithmParameterException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //byte[] decordedValue;
        //decordedValue = new BASE64Decoder().decodeBuffer(myData);
        //decordedValue = myData.getBytes("ISO-8859-1");
          //byte[] decValue = cipher.doFinal(myData.getBytes());
        //Base64.getMimeEncoder().encodeToString(cipher.doFinal(myData.getBytes()));
            //String decryptedValue = new String(decValue);
        byte[] decodedValue  = new Base64().decode(myData.getBytes());



          String clearText = "ljfva09876FK";


          //String encodedValue  = new Base64().encodeAsString(clearText.getBytes("UTF-16"));



          byte[] cipherBytes = cipher1.doFinal(clearText.getBytes("UTF-16LE"));
          //String cipherText = new String(cipherBytes, "UTF8");
          String encoded = Base64.encodeBase64String(cipherBytes);
          System.out.println(encoded);


            byte[] decValue =    cipher.doFinal(decodedValue);

            System.out.println(new String(decValue, StandardCharsets.UTF_16LE));

【问题讨论】:

  • 我试图接受你的回答,它说我没有足够的声望点。我是新手,谢谢你的帮助!

标签: java .net vb.net encryption aes


【解决方案1】:

您的迭代计数应为 1000(而不是 1),这是 RFC 中建议的最小值和(未指定的)默认值 Rfc2898DeriveBytes

对于本文档中的方法,至少 推荐 1000 次迭代

所以这将转化为:

PBEKeySpec pbeKeySpec = new PBEKeySpec(pw.toCharArray(), salt, 1000, 384);

在 Java 代码中。请注意,强烈建议使用更高的迭代次数,尤其是在允许使用较弱密码的情况下。 40K-100K 现在差不多是最低了。


错误命名的Unicode实际上是.NET中的UTF-16,所以你应该使用:

new String(decValue, StandardCharsets.UTF_16LE)

在 Java 代码的最后一个 println 语句中。

【讨论】:

  • 两者都在使用 1 次迭代,因此在发布的示例中应该不会出现问题。
  • 你如何正确解码,而我的却给了我一个错误。请查看我刚刚更新的修改后的代码。
  • @VinnieSensese 太好了,感谢您的接受。我们现在可以删除所有的 cmets,因为它们不再需要了。我现在将删除除此之外的所有内容。 PS你现在应该可以投票了,你已经获得了足够的积分。
【解决方案2】:

感谢 Maarten Bodewes,这是答案

String myData = "kgxCSfBSw5BRxmjgc4qYhwN12dxG0=";
    byte[] salt = new byte[] {0x49, 0x76, 0x61, 0x6E, 0x20, 0x4D, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76};
    String pw  = "kmjfds(#1231SDSA()#rt32geswfkjFJDSKFJDSFd";

    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
    PBEKeySpec pbeKeySpec = new PBEKeySpec(pw.toCharArray(), salt, 1000, 384);
    Key secretKey = factory.generateSecret(pbeKeySpec);
    byte[] key = new byte[32];
    byte[] iv = new byte[16];
    System.arraycopy(secretKey.getEncoded(), 0, key, 0, 32);
    System.arraycopy(secretKey.getEncoded(), 32, iv, 0, 16);


    SecretKeySpec secretSpec = new SecretKeySpec(key, "AES");
    AlgorithmParameterSpec ivSpec = new IvParameterSpec(iv);
    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    try {
        cipher.init(Cipher.DECRYPT_MODE,secretSpec,ivSpec);
    } catch (InvalidKeyException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InvalidAlgorithmParameterException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    //byte[] decordedValue;
    //decordedValue = new BASE64Decoder().decodeBuffer(myData);
    //decordedValue = myData.getBytes("ISO-8859-1");
      //byte[] decValue = cipher.doFinal(myData.getBytes());
    //Base64.getMimeEncoder().encodeToString(cipher.doFinal(myData.getBytes()));
        //String decryptedValue = new String(decValue);
    byte[] decodedValue  = new Base64().decode(myData.getBytes());


    byte[] decValue =    cipher.doFinal(decodedValue);

        System.out.println(new String(decValue, StandardCharsets.UTF_16LE));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-04
    • 2021-01-15
    • 1970-01-01
    • 2016-03-30
    • 2014-03-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多