摘要: 我正在尝试解密(并最终加密并返回)AES128 加密的文件。AES 密钥使用 libcrypt 的 RSA 提供程序进行加密。当我尝试使用 C# 和 BouncyCastle 在 Windows 7 上解密 AESKey 时,当我调用“ProcessBlock”时会引发“块截断”错误。我尝试将数据转换为 BigEndian,当我尝试创建 RsaKeyParameters 时,我会得到“不是有效的 RSA 指数”。
加密是在 linux 系统上使用 libgcrypt 1.2x 完成的。我认为这是一个填充问题,因为这段代码表明没有使用填充。
gcry_sexp_build(&PlainKeyExp, NULL, "(data (flags raw) (value %s))", AESKey );
不幸的是,我无法更改原始系统。我在下面包含代码示例和键以提供帮助。在过去的 3 天里,这一直让我发疯。我已经搜索了 interwebz 并没有找到解决方案。预先感谢您的帮助。
原始代码片段
static const char RSAPrivateKey[] =
"(private-key"
" (rsa"
" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)"
" (e #010001#)"
" (d #046129f2489d71579be0a75fe029bd6cdb574ebf57ea8a5b0fda942cab943b11"
" 7d7bb95e5d28875e0f9fc5fcc06a72f6d502464dabded78ef6b716177b83d5bd"
" c543dc5d3fed932e59f5897e92e6f58a0f33424106a3b6fa2cbf877510e4ac21"
" c3ee47851e97d12996222ac3566d4ccb0b83d164074abf7de655fc2446da1781#)"
" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
" fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)"
" (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
" 35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)"
" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
" ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))";
Error = gcry_sexp_sscan(&PublicKey, NULL, RSAPublicKey, strlen(RSAPublicKey));
if ( Error ) { goto Return; }
Error = gcry_sexp_sscan(&PrivateKey, NULL, RSAPrivateKey, strlen(RSAPrivateKey));
if ( Error ) { goto Return; }
Error = gcry_sexp_build(&PlainKeyExp, NULL, "(data (flags raw) (value %s))", AESKey );
gpg_strerror_r(Error, Output, 500);
if ( Error ) { goto Return; }
Error = gcry_pk_encrypt(&Encrypted, PlainKeyExp, PublicKey);
if ( Error ) { goto Return; }
if ( gcry_sexp_sprint(Encrypted, GCRYSEXP_FMT_CANON, Output, 500) <= 0 ) { Error = TRUE; goto Return; }
Encrypted = gcry_sexp_find_token(Encrypted, "a", 0);
if ( Encrypted == NULL ) { Error = TRUE; goto Return; }
if ( gcry_sexp_sprint(Encrypted, GCRYSEXP_FMT_ADVANCED, Output, 500) <= 0 ) { Error = TRUE; goto Return; }
if ( strtok(Output, "#") != NULL ) {
Output2 = strtok(NULL, "#");
if ( Output2 != NULL ) { sprintf(EncryptedKey,"%s", Output2); }
else { Error = TRUE; }
} else { Error = TRUE; }
解码代码片段
var modulus ="00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251";
var privateExponent ="046129f2489d71579be0a75fe029bd6cdb574ebf57ea8a5b0fda942cab943b117d7bb95e5d28875e0f9fc5fcc06a72f6d502464dabded78ef6b716177b83d5bdc543dc5d3fed932e59f5897e92e6f58a0f33424106a3b6fa2cbf877510e4ac21c3ee47851e97d12996222ac3566d4ccb0b83d164074abf7de655fc2446da1781";
var encryptedAesKey ="77FD84196959DDE3C367952B3C25B34582B489A705FB3C61D69D04DDA16B011F6358F32834DD76BF81A1DF28106F377FF1125F91CA39BB92D293B8F5134C15C17DE1157390723301A01B938489E04DA1D8D4A70511F0FF2508984710CEB3F18D4BA929C18487A0977011BDE169DBBF3047646FBFBC50ED5A02FC40E53E59B8CD";
try
{
// Convert to biginteger
var bcMod = new Org.BouncyCastle.Math.BigInteger(Hex.Decode(modulus));
var bcPrivateExponent = new Org.BouncyCastle.Math.BigInteger(Hex.Decode(privateExponent));
byte[] decodedAesKey = Hex.Decode(encryptedAesKey);
// Init bouncyCastle
var privParameters = new RsaKeyParameters(true, bcMod, bcPrivateExponent);
var eng = new Pkcs1Encoding(new RsaEngine());
eng.Init(false, privParameters);
var ret = eng.ProcessBlock(decodedAesKey, 0, 128);
}
catch (Exception e)
{
Console.WriteLine(e);
}