我在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());
}
}
答案 0 :(得分:1)
如果您的salt应该是7个字节长,如VB.NET代码Dim bytes As Byte() = New Byte(7) {}
中所示,您应该声明它:
byte[] bytes = new byte[7];
您尝试使用的PBEKeySpec
构造函数是PBEKeySpec(char[] password, byte[] salt, int iterationCount, int keyLength)
,其中您使用请求12次迭代,输出长度为1000.
您需要使用
new PBEKeySpec(CertClaveDesencriptada.toCharArray(), bytes, 1000, 384);
其中384表示32 + 16字节的比特。