使用RSACryptoServiceProvider进行公钥加密

Joh*_*ohn 14 .net c# cryptography rsa encryption-asymmetric

我已经在CodeProject上发表了一篇文章,解释了如何使用RSA提供程序加密和解密:

RSA私钥加密

虽然2009年的旧版本是错误的,但新的2012版本(支持System.Numerics.BigInteger)似乎更可靠.这是什么版本缺少虽然是一种方法加密公共密钥和解密使用私有密钥.

所以,我自己尝试了,但是当我解密时却得到了垃圾.我不熟悉RSA提供商,所以我在这里很黑.很难找到关于它应该如何工作的更多信息.

有人看到这有什么问题吗?以下是带有PUBLIC密钥的ENcryption:

// 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();
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我是否使用提供商提供的大"D"?可能不是因为它是没有"D"的公钥.

然后是对应的(使用PRIVATE键进行DEcrypting):

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;
Run Code Online (Sandbox Code Playgroud)

我需要"D"或指数吗?

显然,我需要加密来兼顾私人 - 公共 - 私人.任何帮助深表感谢!

Iva*_*nin 17

以此编码/解码示例为例

        byte[] toEncryptData = Encoding.ASCII.GetBytes("hello world");

        //Generate keys
        RSACryptoServiceProvider rsaGenKeys = new RSACryptoServiceProvider();
        string privateXml = rsaGenKeys.ToXmlString(true);
        string publicXml = rsaGenKeys.ToXmlString(false);

        //Encode with public key
        RSACryptoServiceProvider rsaPublic = new RSACryptoServiceProvider();
        rsaPublic.FromXmlString(publicXml);
        byte[] encryptedRSA = rsaPublic.Encrypt(toEncryptData, false);
        string EncryptedResult = Encoding.Default.GetString(encryptedRSA);


        //Decode with private key
        var rsaPrivate = new RSACryptoServiceProvider();
        rsaPrivate.FromXmlString(privateXml);
        byte[] decryptedRSA = rsaPrivate.Decrypt(encryptedRSA, false);
        string originalResult = Encoding.Default.GetString(decryptedRSA);
Run Code Online (Sandbox Code Playgroud)

  • 最初的问题是询问两个方向的示例。您的代码显示仅使用私钥进行解密,而不显示如何使用公钥进行解密。 (2认同)

Dar*_*l42 10

这是一个例子:

    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;
    }
Run Code Online (Sandbox Code Playgroud)

  • 叹息......所以...你的观点是构造函数不尊重公钥?...编写自己的...这是一个示例,说明如何进行数学计算以及如何阅读关键组件...没有免费复制和粘贴生产代码与waranties ...随意提出你自己的答案... (2认同)