java - 如何在 JAVA 中的 Rijndael 加密等效项中获得正确的 KEY 和 IV

标签 java vb.net encryption rijndael

我在 VB.Net 中有一段带有 Rijndael 加密算法的代码:

Public Function DesencriptarCertificado(ByVal pCertificado As String, ByVal pClave As String) As Byte()
    Dim byteCertificadoDescencriptado As Byte() = Nothing
    Dim Algoritmo As SymmetricAlgorithm = New RijndaelManaged()
    Dim CertClaveDesencriptada As String = ""

    CertClaveDesencriptada = DesencriptarString(pClave, "")
    Transform(CertClaveDesencriptada, Algoritmo)


    Dim ICryptoTransform As ICryptoTransform = Algoritmo.CreateDecryptor()
        byteCertificadoDescencriptado = HexToByte(pCertificado)
        byteCertificadoDescencriptado = ICryptoTransform.TransformFinalBlock(byteCertificadoDescencriptado, 0, byteCertificadoDescencriptado.Length)
    Return byteCertificadoDescencriptado
End Function

Public Sub Transform(ByVal pClave As String, ByRef pAlgoritmo As SymmetricAlgorithm)

    Dim bytes As Byte() = New Byte(7) {}
    Dim BytesClave As Byte() = Encoding.ASCII.GetBytes(pClave)
    Dim length As Integer = Math.Min(BytesClave.Length, bytes.Length)

    For i As Integer = 0 To length - 1
        bytes(i) = BytesClave(i)
    Next

    Dim key As New Rfc2898DeriveBytes(pClave, bytes)
    //ASIGNO BYTES A KEY E IV
    pAlgoritmo.Key = key.GetBytes(pAlgoritmo.KeySize \ 8)
    pAlgoritmo.IV = key.GetBytes(pAlgoritmo.BlockSize \ 8)
End Sub

问题是JAVA中的IV和KEY没有获得相同的字节,因此签名不相同,如果我使用VB.Net中生成的相同字节手动初始化KEY和IV,它可以正常工作,但是当然这是不可行的,因为它只适用于特定的证书,并且想法是它可以通用,在搜索后我尝试了一些变体但没有成功,我无法获得 KEY 和 IV,我将不胜感激任何帮助与主题。

Java代码

public byte[] DesencriptarCertificado(String pCertificado, String pClave) throws NoSuchAlgorithmException, InvalidKeySpecException, UnsupportedEncodingException, NoSuchPaddingException, InvalidAlgorithmParameterException, NoSuchProviderException, ShortBufferException, IOException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {

    try {
        String CertClaveDesencriptada = DesencriptarString(pClave, "");

        ////////////Transform//////////////
        byte[] bytes = new byte[8];
        byte[] BytesClave = CertClaveDesencriptada.getBytes();
        int length = Math.min(BytesClave.length, bytes.length);

        for (int i = 0; i < length; i++) {
            bytes[i] = BytesClave[i];
        }

        SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
        KeySpec pbeKeySpec = new PBEKeySpec(CertClaveDesencriptada.toCharArray(), bytes, 12, 1000);
        Key secretKey = factory.generateSecret(pbeKeySpec);
        byte[] encoded = secretKey.getEncoded();

        byte[] KEY = new byte[32];
        byte[] IV = new byte[16];

        //ASIGNO BYTES A KEY E IV
        System.arraycopy(encoded, 0, KEY, 0, 32); 
        System.arraycopy(encoded, 32, IV, 0, 16);

        SecretKeySpec secret = new SecretKeySpec(key, "Rijndael");
        AlgorithmParameterSpec ivSpec = new IvParameterSpec(IV);
        _cipherDecrypEncrypt = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
        _cipherDecrypEncrypt.init(Cipher.DECRYPT_MODE, secret, ivSpec);


        ///////////////DESENCRIPTAR CERTIFICADO/////////////////////
        byte[] beforeEncrypt = HexToByte(pCertificado);
        byte[] byteCertificadoDescencriptado = _cipherDecrypEncrypt.doFinal(beforeEncrypt);

        return byteCertificadoDescencriptado;

    } catch (InvalidKeyException e) {
        throw new TAFACE2ApiEntidad.TAException(e.getMessage());
    } catch (IllegalBlockSizeException e) {
        System.out.println(e);
        throw new TAFACE2ApiEntidad.TAException(e.getMessage());
    } catch (BadPaddingException e) {
        System.out.println(e);
        throw new TAFACE2ApiEntidad.TAException(e.getMessage());
    }

}

最佳答案

  1. 如果您的盐应该是 7 个字节长,如 VB.NET 代码中所示 Dim bytes As Byte() = New Byte(7) {},您应该声明它是这样的:

    byte[] bytes = new byte[7];
    
  2. 您尝试使用的 PBEKeySpec 构造函数是 PBEKeySpec(char[] password, byte[] salt, int iterationCount, int keyLength)您使用请求 12 次迭代来获得 1000 的输出长度。

    您需要使用

    new PBEKeySpec(CertClaveDesencriptada.toCharArray(), bytes, 1000, 384);
    

    其中 384 表示 32 + 16 位字节。

关于java - 如何在 JAVA 中的 Rijndael 加密等效项中获得正确的 KEY 和 IV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44202499/

相关文章:

javascript - 为什么浏览器扩展比纯粹的基于 Web 的应用程序更安全?

sql - 加密 - 在 SQl Server 2008 中用法语单词解密

java - 我应该把这个参数放在哪里以及如何运行这个程序?

.net - 捕获导致内存不足异常的位图

php - 无法登录我的哈希密码,但有一个用户可以登录

vb.net - 在 LINQ 语句中使用 OrElse

c# - 如何开始在 .NET 中创建应用程序 API

用于调制解调器的 Java SMS API

java - URLConnection URL 包含重音字符的编码问题

java - Spring-Data-Jpa 保存: Related entities saved as null which are not