I am trying to decrypt a message that has been encrypted using AES-128 Symmetric encryption and then RSA-1024 Asymmetric encryption on the generated symmetric key. I receive the encrypted AES key and the encrypted message, extract the private key from the pfx file and then proceed with the decryption of the symmetric key. After that, I try to decrypt the encrypted message using the decrypted AES key.
Following is my code:
// Get the private key
PrivateKey privateKey = (PrivateKey) keyStore.getKey(selectedAlias, "password".toCharArray());
System.out.println("Key information " + privateKey.getAlgorithm() + " " + privateKey.getFormat());
// Load aesSessionKey and encryptedMessage
byte[] aesSessionKey = ...
byte[] encryptedMessage = ...
// RSA Decryption of Encrypted Symmetric AES key - 128 bits
Cipher rsaCipher = Cipher.getInstance("RSA", "BC");
rsaCipher.init(Cipher.UNWRAP_MODE, privateKey);
Key decryptedKey = rsaCipher.unwrap(aesSessionKey, "AES", Cipher.SECRET_KEY);
System.out.println("Decrypted Key Length: " + decryptedKey.getEncoded().length);
SecretKeySpec decrypskeySpec = new SecretKeySpec(decryptedKey.getEncoded(), "AES");
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5PADDING", "BC");
cipher.init(Cipher.DECRYPT_MODE, decryptedKey, new IvParameterSpec(new byte[16]));
byte[] message = cipher.doFinal(encryptedMessage);
System.out.println(new String(message, "UTF-8"));
The problem is that the size of the decrypted AES key is 128 bytes and not 16 bytes as I was expecting. I get the following exception:
Key information RSA PKCS#8
Decrypted Key Length: 128
java.security.InvalidKeyException: Key length not 128/192/256 bits.
at org.bouncycastle.jce.provider.JCEBlockCipher.engineInit(Unknown Source)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at com.simarks.services.PKCS12.run(PKCS12.java:74)
at com.simarks.services.PKCS12.main(PKCS12.java:34)
I am new to Java Cryptography. I have checked numerous other questions and tried several different approaches (like using DECRYPT_MODE instead of UNWRAP_MODE) but I get the same error. Any help will be much appreciated.
EDIT: The client code encrypting the message is this:
PBYTE pInputData = NULL;
DWORD dwInputSize = 0;
PBYTE pCertData = NULL;
DWORD dwCertSize = 0;
PCCERT_CONTEXT pCertContext = NULL;
HCRYPTPROV hCryptProv = NULL;
HCRYPTKEY hPublicKey = NULL;
HCRYPTKEY hSessionKey = NULL;
BYTE InitializationVector[ 32 ] = { 0 };
DWORD PKCS5Padding = PKCS5_PADDING;
DWORD CBCMode = CRYPT_MODE_CBC;
PSIMPLEBLOB pKeyBlob = NULL;
DWORD dwBlobSize = 0;
DWORD dwKeySize = 0;
PBYTE pEncryptedData = NULL;
DWORD dwEncryptedDataSize = 0;
HRESULT hr = S_FALSE;
if( FAILED( hr = ReadBinaryFile( InputFile, &pInputData, &dwInputSize ) ) ) goto EncryptExit;
if( FAILED( hr = ReadBinaryFile( CertFile, &pCertData, &dwCertSize ) ) ) goto EncryptExit;
if( ( pCertContext = CertCreateCertificateContext( PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, pCertData, dwCertSize ) ) == NULL ) goto EncryptExit;
if( !CryptAcquireContext( &hCryptProv, NULL, GetMsAesProviderName(), PROV_RSA_AES, 0 ) ) goto EncryptExit;
if( !CryptImportPublicKeyInfo( hCryptProv, PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, &pCertContext->pCertInfo->SubjectPublicKeyInfo, &hPublicKey ) ) goto EncryptExit;
if( !CryptGenKey( hCryptProv, AlgId, CRYPT_EXPORTABLE, &hSessionKey ) ) goto EncryptExit;
if( !CryptSetKeyParam( hSessionKey, KP_IV, InitializationVector, 0 ) ) goto EncryptExit;
if( !CryptSetKeyParam( hSessionKey, KP_PADDING, (PBYTE)&PKCS5Padding, 0 ) ) goto EncryptExit;
if( !CryptSetKeyParam( hSessionKey, KP_MODE, (PBYTE)&CBCMode, 0 ) ) goto EncryptExit;
if( !CryptExportKey( hSessionKey, hPublicKey, SIMPLEBLOB, 0, NULL, &dwBlobSize ) ) goto EncryptExit;
if( ( pKeyBlob = (PSIMPLEBLOB)malloc( dwBlobSize ) ) == NULL ) { hr = E_OUTOFMEMORY; goto EncryptExit; }
if( !CryptExportKey( hSessionKey, hPublicKey, SIMPLEBLOB, 0, (PBYTE)pKeyBlob, &dwBlobSize ) ) goto EncryptExit;
dwKeySize = dwBlobSize - sizeof( BLOBHEADER ) - sizeof( ALG_ID );
dwEncryptedDataSize = dwInputSize;
if( !CryptEncrypt( hSessionKey, NULL, TRUE, 0, NULL, &dwEncryptedDataSize, 0 ) ) goto EncryptExit;
if( ( pEncryptedData = (PBYTE)malloc( dwEncryptedDataSize ) ) == NULL ) { hr = E_OUTOFMEMORY; goto EncryptExit; }
CopyMemory( pEncryptedData, pInputData, dwInputSize );
if( !CryptEncrypt( hSessionKey, NULL, TRUE, 0, pEncryptedData, &dwInputSize, dwEncryptedDataSize ) ) goto EncryptExit;
if( FAILED( hr = WriteBinaryFile( OutputFile, pEncryptedData, dwInputSize ) ) ) goto EncryptExit;
hr = WriteBinaryFile( KeyFile, pKeyBlob->Key, dwKeySize );
EncryptExit:
Cipher.getInstance("RSA/ECB/PKCS1Padding", "BC")instead of using the defaults for"RSA"? For this kind of functionality you could also try the default Oracle providers by the way (so try removing the"BC"argument as well. Also print out the type of the returned key. - Maarten Bodewes