当前位置: 首页 > 知识库问答 >
问题:

RSA解密后无效的AES密钥大小

轩辕涵亮
2023-03-14
  // 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"));
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)
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:

共有1个答案

陈嘉荣
2023-03-14

经过一些研究,我通过颠倒AessessionKey的字节来解决这个问题:

org.apache.commons.lang.ArrayUtils.reverse(encryptedSessionKey);

显然,CryptoAPI结构通常以小端顺序表示数据,但Java(和.NET)使用大端顺序。以下是我找到解决方案的一些链接:

  • RSA加密/解密:.NET、Java2和CryptoAPI
  • re:MS加密API和Java安全API(KeyValue)
  • EncryptTo/DecryptTo:在.NET中使用CryptoAPI证书存储进行加密
 类似资料:
  • 这是我的密码 抱歉,如果我的代码一团糟。

  • 问题内容: 我正在编写一个用于传输文件的小型应用程序,或多或少地将其作为一种学习更多编程加密基础的方法。这个想法是生成一个RSA密钥对,交换公共密钥,并发送AES iv和密钥以进一步解密。我想用接收者的RSA公钥加密AES密钥,如下所示: 然后,我将密钥值写给接收器,并按如下方式解密: 在控制台的另一端,我将其作为输出: 此外,如果我创建一个大小为16的字节数组,并将cipher.doFinal(

  • 但这总是给我以下的例外- 我的键盘生成逻辑- 我的加密逻辑- Base64 Util方法-

  • 也许你能帮我。非常感谢!

  • 我正在使用Safenet HSM(硬件安全模块)来存储我的加密密钥,并且我正在尝试使用JavaAPI和SunPKCS11解包使用RSA加密的密钥(AES/DES)。我想安全地执行此操作,以便无法从HSM中提取解包的AES/DES密钥(就像RSA私钥值是不可见的)。但是,在解包后,解包密钥的值在HSM之外的密钥对象中是可见的。 这是我的代码: 如何告诉代码不要泄露未包装的密钥?我必须在PKCS11配

  • 我的进程: 1。生成对称密钥 2。使用对称密钥 3加密数据。使用RSA 4加密对称密钥。发送加密密钥和数据 5。使用RSA 6解密加密的对称密钥。使用对称密钥 7解密数据。已完成