将.Net解密转换为Java [英] Converting .Net decryption to Java

查看:96
本文介绍了将.Net解密转换为Java的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前,我正在一个项目中,他们使用AES加密和RFC2898派生字节进行加密.这是我提供的解密方法.现在,我需要在Java中实现它.

Currently I'm working on a project where they use AES encryption with RFC2898 derived bytes. This the decryption method that I've provided. Now I need to implement it in java.

private string Decrypt(string cipherText)
    {
        string EncryptionKey = "MAKV2SPBNI657328B";
        cipherText = cipherText.Replace(" ", "+");
        byte[] cipherBytes = Convert.FromBase64String(cipherText);
        using (Aes encryptor = Aes.Create())
        {
            Rfc2898DeriveBytes pdb = new Rfc2898DeriveBytes(EncryptionKey, new byte[] {
                0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76 
                });
            encryptor.Key = pdb.GetBytes(32);
            encryptor.IV = pdb.GetBytes(16);
            using (MemoryStream ms = new MemoryStream())
            {
                using (CryptoStream cs = new CryptoStream(ms, encryptor.CreateDecryptor(), CryptoStreamMode.Write))
                {
                    cs.Write(cipherBytes, 0, cipherBytes.Length);
                    cs.Close();
                }
                cipherText = Encoding.Unicode.GetString(ms.ToArray());
            }
        }
        return cipherText;
    }

这是我到目前为止所要做的:

This is what I go so far:

   String EncryptionKey = "MAKV2SPBNI657328B";
   String userName="5L9p7pXPxc1N7ey6tpJOla8n10dfCNaSJFs%2bp5U0srs0GdH3OcMWs%2fDxMW69BQb7"; 
   byte[] salt =  new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76};
   try {
        userName = java.net.URLDecoder.decode(userName, StandardCharsets.UTF_8.name());
        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        PBEKeySpec pbeKeySpec = new PBEKeySpec(EncryptionKey.toCharArray(), salt, 1000);
        Key secretKey = factory.generateSecret(pbeKeySpec);
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE, secretKey);
        byte[] result = cipher.doFinal(userName.getBytes("UTF-8"));
        System.out.println(result.toString());
   } catch (Exception e) {
        System.out.println(e.getMessage());
   }

但是我收到如下错误:

找不到密钥长度java.security.spec.InvalidKeySpecException:找不到密钥长度

Key length not found java.security.spec.InvalidKeySpecException: Key length not found

推荐答案

Java代码中存在一些问题:必须指定要生成的位数,除了必须派生IV的密钥之外,IV必须是应用于解密时,在对纯文本进行解码时,必须对密文进行Base64解码,并且必须使用Utf-16LE.详细信息:

There are some issues in the Java code: The number of bits to be generated must be specified, besides the key the IV must be derived, the IV must be applied for decryption, the ciphertext must be Base64 decoded and Utf-16LE must be used when decoding the plaintext. In detail:

  • 实例化

  • When instantiating PBEKeySpec, the number of bits to be generated must be specified in the 4th parameter. Since both, key (256 bits) and IV (128 bits) are derived in the C# code, 384 (= 256 + 128) must be applied:

SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
PBEKeySpec pbeKeySpec = new PBEKeySpec(encryptionKey.toCharArray(), salt, 1000, 384);   

  • 前256位是密钥,后128位是IV:

  • The first 256 bits are the key, the following 128 bits the IV:

    byte[] derivedData = factory.generateSecret(pbeKeySpec).getEncoded();
    byte[] key = new byte[32];
    byte[] iv = new byte[16];
    System.arraycopy(derivedData, 0, key, 0, key.length);
    System.arraycopy(derivedData, key.length, iv, 0, iv.length);
    

  • 必须在

  • 密文必须先经过Base64解码,然后才能解密:

  • The ciphertext must be Base64-decoded before it can be decrypted:

    byte[] result = cipher.doFinal(Base64.getDecoder().decode(userName));
    

  • 必须使用Utf-16LE编码(对应于

  • 请注意,对于 CBC 模式,重要的是,出于安全考虑,IV组合仅使用一次.对于此处的C#(或Java)代码,这意味着对于相同的密码,每次加密都必须使用不同的盐,请参见此处.

    Note that for CBC mode, it's important that a key/IV combination is only used once for security reasons. For the C# (or Java) code here, this means that for the same password, different salts must be used for each encryption, see here.

    这篇关于将.Net解密转换为Java的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆