問題描述
一段時間以來,我在 CodeProject 上看過一篇文章,其中解釋了如何使用 RSA 提供程序進行加密和解密:
I have been over an article at CodeProject a for a while that explains how to encrypt and decrypt using the RSA provider:
RSA 私鑰加密
雖然 2009 年的舊版本有問題,但 2012 年的新版本(支持 System.Numerics.BigInteger)似乎更可靠.不過,這個版本缺少的是一種使用 public 密鑰加密 并使用 private 密鑰解密 的方法.
While the old version from 2009 was buggy, the new 2012 version (with System.Numerics.BigInteger support) seems more reliable. What this version lacks though is a way to encrypt with a public key and decrypt using the private key.
所以,我自己嘗試過,但解密時會出現垃圾.我不熟悉 RSA 提供商,所以我在這里一無所知.很難找到更多關于這應該如何工作的信息.
So, I tried it myself but get garbage when I decrypt. I'm not familiar with the RSA provider, so I'm in the dark here. It's hard to find more info on how this is supposed to work.
有人知道這有什么問題嗎?以下是使用公鑰加密:
// Add 4 byte padding to the data, and convert to BigInteger struct
BigInteger numData = GetBig( AddPadding( data ) );
RSAParameters rsaParams = rsa.ExportParameters( false );
//BigInteger D = GetBig( rsaParams.D ); //only for private key
BigInteger Exponent = GetBig( rsaParams.Exponent );
BigInteger Modulus = GetBig( rsaParams.Modulus );
BigInteger encData = BigInteger.ModPow( numData, Exponent, Modulus );
return encData.ToByteArray();
執行此操作時是否使用提供商提供的大D"?可能不是,因為它是沒有D"的公鑰.
Do I use the big "D" from the provider when I do this? Probably not since it's the public key which doesn't have the "D".
然后是對應的(使用 PRIVATE 密鑰解密):
BigInteger numEncData = new BigInteger( cipherData );
RSAParameters rsaParams = rsa.ExportParameters( true );
BigInteger D = GetBig( rsaParams.D );
//BigInteger Exponent = GetBig( rsaParams.Exponent );
BigInteger Modulus = GetBig( rsaParams.Modulus );
BigInteger decData = BigInteger.ModPow( numEncData, D, Modulus );
byte[] data = decData.ToByteArray();
byte[] result = new byte[ data.Length - 1 ];
Array.Copy( data, result, result.Length );
result = RemovePadding( result );
Array.Reverse( result );
return result;
這里需要D"還是指數?
Do I need the "D" or the Exponent here?
顯然,我需要加密貨幣在私人-公共-公共-私人兩種方式下工作.非常感謝任何幫助!
推薦答案
這里有一個例子:
public static void rsaPlayground()
{
byte[] data = new byte[] { 1, 2, 3, 4, 5 };
RSACryptoServiceProvider csp = new RSACryptoServiceProvider();//make a new csp with a new keypair
var pub_key = csp.ExportParameters(false); // export public key
var priv_key = csp.ExportParameters(true); // export private key
var encData = csp.Encrypt(data, false); // encrypt with PKCS#1_V1.5 Padding
var decBytes = MyRSAImpl.plainDecryptPriv(encData, priv_key); //decrypt with own BigInteger based implementation
var decData = decBytes.SkipWhile(x => x != 0).Skip(1).ToArray();//strip PKCS#1_V1.5 padding
}
public class MyRSAImpl
{
private static byte[] rsaOperation(byte[] data, BigInteger exp, BigInteger mod)
{
BigInteger bData = new BigInteger(
data //our data block
.Reverse() //BigInteger has another byte order
.Concat(new byte[] { 0 }) // append 0 so we are allways handling positive numbers
.ToArray() // constructor wants an array
);
return
BigInteger.ModPow(bData, exp, mod) // the RSA operation itself
.ToByteArray() //make bytes from BigInteger
.Reverse() // back to "normal" byte order
.ToArray(); // return as byte array
/*
*
* A few words on Padding:
*
* you will want to strip padding after decryption or apply before encryption
*
*/
}
public static byte[] plainEncryptPriv(byte[] data, RSAParameters key)
{
MyRSAParams myKey = MyRSAParams.fromRSAParameters(key);
return rsaOperation(data, myKey.privExponent, myKey.Modulus);
}
public static byte[] plainEncryptPub(byte[] data, RSAParameters key)
{
MyRSAParams myKey = MyRSAParams.fromRSAParameters(key);
return rsaOperation(data, myKey.pubExponent, myKey.Modulus);
}
public static byte[] plainDecryptPriv(byte[] data, RSAParameters key)
{
MyRSAParams myKey = MyRSAParams.fromRSAParameters(key);
return rsaOperation(data, myKey.privExponent, myKey.Modulus);
}
public static byte[] plainDecryptPub(byte[] data, RSAParameters key)
{
MyRSAParams myKey = MyRSAParams.fromRSAParameters(key);
return rsaOperation(data, myKey.pubExponent, myKey.Modulus);
}
}
public class MyRSAParams
{
public static MyRSAParams fromRSAParameters(RSAParameters key)
{
var ret = new MyRSAParams();
ret.Modulus = new BigInteger(key.Modulus.Reverse().Concat(new byte[] { 0 }).ToArray());
ret.privExponent = new BigInteger(key.D.Reverse().Concat(new byte[] { 0 }).ToArray());
ret.pubExponent = new BigInteger(key.Exponent.Reverse().Concat(new byte[] { 0 }).ToArray());
return ret;
}
public BigInteger Modulus;
public BigInteger privExponent;
public BigInteger pubExponent;
}
這篇關于使用 RSACryptoServiceProvider 進行公鑰加密的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!