如何使用C#Bouncy Castle对使用Libgcrypt raw标志加密的AES密钥进行解密 [英] How do I decrypt an AES key using C# Bouncy Castle that was encrypted using Libgcrypt raw flag

查看:611
本文介绍了如何使用C#Bouncy Castle对使用Libgcrypt raw标志加密的AES密钥进行解密的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

摘要:
我正在尝试解密(并最终加密和返回)AES128加密的文件。 AES密钥使用libcrypt的RSA提供程序加密。当我试图解密AESKey在Windows 7使用C#& BouncyCastle当我调用ProcessBlock时抛出块截断错误。我尝试将数据转换为BigEndian,当我尝试创建RsaKeyParameters时,我会得到一个不是有效的RSA指数。



加密是使用libgcrypt 1.2x在linux系统上。我认为这是一个填充问题,因为这段代码表示没有使用填充。
gcry_sexp_build(& PlainKeyExp,NULL,(data(flags raw)(value%s)),AESKey);



不幸的是我不能改变原始系统。我包括代码示例&键帮助。这已经驱使我疯了过去3天。我已经擦洗了interwebz,没有找到一个解决方案。 pre> static const char RSAPrivateKey [] =
(私钥
(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返回; }
Encrypted = gcry_sexp_find_token(Encrypted,a,0);
if(Encrypted == NULL){Error = TRUE; goto返回; }

if(gcry_sexp_sprint(Encrypted,GCRYSEXP_FMT_ADVANCED,Output,500)< = 0){Error = TRUE; goto返回; }
if(strtok(Output,#)!= NULL){
Output2 = strtok(NULL,#);
if(Output2!= NULL){sprintf(EncryptedKey,%s,Output2); }
else {Error = TRUE; }
} else {Error = TRUE; }

解码代码段

  VAR模数=00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251; 

VAR privateExponent =046129f2489d71579be0a75fe029bd6cdb574ebf57ea8a5b0fda942cab943b117d7bb95e5d28875e0f9fc5fcc06a72f6d502464dabded78ef6b716177b83d5bdc543dc5d3fed932e59f5897e92e6f58a0f33424106a3b6fa2cbf877510e4ac21c3e​​e47851e97d12996222ac3566d4ccb0b83d164074abf7de655fc2446da1781;

VAR encryptedAesKey =77FD84196959DDE3C367952B3C25B34582B489A705FB3C61D69D04DDA16B011F6358F32834DD76BF81A1DF28106F377FF1125F91CA39BB92D293B8F5134C15C17DE1157390723301A01B938489E04DA1D8D4A70511F0FF2508984710CEB3F18D4BA929C18487A0977011BDE169DBBF3047646FBFBC50ED5A02FC40E53E59B8CD;

try
{
//转换为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);
}


解决方案

新的Pkcs1Encoding()构造函数调用并直接使用 RsaEngine 。如果没有填充,则不需要删除或验证它。



请注意,填充是创建基于安全RSA的密文的要求。所以这是可以克服兼容性问题,但系统应该立即更换。


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);
}

解决方案

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.

这篇关于如何使用C#Bouncy Castle对使用Libgcrypt raw标志加密的AES密钥进行解密的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆