问题
Summary: I am attempting to decrypt (and eventually encrypt and return) files that are AES128 encrypted. The AES key is encrypted using libcrypt's RSA provider. When I attempt to decrypt the AESKey on Windows 7 using C# & BouncyCastle a "block truncated" error is thrown when I call "ProcessBlock". I have tried converting the data to BigEndian and I'll get a "Not a valid RSA exponent" when I try to create the RsaKeyParameters.
The encryption was done using libgcrypt 1.2x on a linux system. I think it's a padding issue since this snippet of code indicates that no padding is used.
gcry_sexp_build(&PlainKeyExp, NULL, "(data (flags raw) (value %s))", AESKey );
Unfortunately I cannot change the originating system. I'm including code samples & keys below to help. This has been driving me insane for the past 3 days. I've scoured the interwebz and have not found a solution. Thank you in advance for your help.
Originating code snippet
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; }
Decoding code snippet
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);
}
回答1:
The answer is simply to remove the new Pkcs1Encoding()
constructor call and directly use RsaEngine
. If there is no padding, then there is no need to remove or validate it.
Note that padding is a requirement to create a secure RSA based ciphertext. So this is OK to overcome compatibility issues, but the system should be replaced right away.
来源:https://stackoverflow.com/questions/17576905/how-do-i-decrypt-an-aes-key-using-c-sharp-bouncy-castle-that-was-encrypted-using