.NET中使用数字证书用RSA算法对数据进行加密和签名

来源:互联网 发布:面板数据回归分析实例 编辑:程序博客网 时间:2024/05/17 04:35

RSA

这种算法1978年就出现了,它是第一个既能用于数据加密也能用于数字签名的算法。它易于理解和操作,也很流行。算法的名字以Ron Rivest, AdiShamir Leonard Adleman发明者的名字命名的。这种加密算法的特点主要是密钥的变化,在DES中只有一个密钥(对称加密)。相当于只有一把钥匙,如果这把钥匙丢了,数据也就不安全了。RSA同时有两把钥匙,公钥与私钥。

加密和解密:发送方利用接收方的公钥对要发送的明文进行加密,接受方利用自己的私钥进行解密,其中公钥和私钥匙相对的,任何一个作为公钥,则另一个就为私钥。用公钥加密,只有用私钥解开,私钥只有自己有,所以他保证了数据不能被别人看到。

签名和验证:发送方用特殊的hash算法,由明文中产生固定长度的摘要,然后利用自己的私钥对形成的摘要进行加密,这个过程就叫签名。接受方利用发送方的公钥解密被加密的摘要得到结果A,然后对明文也进行hash操作产生摘要B。最后把AB作比较。此方式可以保证发送方的身份不可抵赖以及保证数据在传输过程中不会被篡改。

  .Net中用来访问证书的对象是X509Certificate2,我们可以用它来加载一个数字证书并获得数字证书中的密钥。

如果证书是以文件的形式保存在本地的话,就可以参考以下提供的方法对数据进行加密/解密以及签名和验证:

具体实现方法为:

引入:

       using System.Security.Cryptography.X509Certificates; System.Security.Cryptography;

using

 

 

 

       using System.Security.Cryptography.X509Certificates;

using System.Security.Cryptography;

 

        /// <summary>

        /// 用公钥对数据加密

        /// </summary>

        /// <param name="message">需要加密的字符串</param>

        /// <returns></returns>

        public byte[] EncryptDataByPublicKey(string message)

        {

 

            //保存明文文件的字节数组

            Byte[] plainTextByte = Encoding.UTF8.GetBytes(message);

 

            //从只包含公钥的证书文件载入证书

            X509Certificate2 myX509Certificate2 = new X509Certificate2(path+ "Certificate//zzServer.cer");

 

            //cer证书中获得含公钥的RSACryptoServiceProvider

            RSACryptoServiceProvider myRSACryptoServiceProvider = (RSACryptoServiceProvider)myX509Certificate2.PublicKey.Key;

 

            //使用RSACryptoServiceProvider把明文字节流加密为密文字节流

            byte[] Cryptograph = myRSACryptoServiceProvider.Encrypt(plainTextByte, false);

 

            //string encrypt = BitConverter.ToString(Cryptograph).Replace("-", "");

 

            return Cryptograph;

        }

 

 

        /// <summary>

        ///用私钥对数据解密

        /// </summary>

        /// <param name="Cryptograph">公钥加密后的密文</param>

        /// <returns>解密后的字符串</returns>

        public string DecryptDataByPrivateKey(byte[] Cryptograph)

        {

 

 

            //从证书文件载入证书,如果含有私钥的,需要提供保存证书时设置的密码

 

            X509Certificate2 myX509Certificate2 = new X509Certificate2(path + "Certificate//zzServer.p12", "mypassword");

 

            //从证书中获得含私钥的RSACryptoServiceProvider

            RSACryptoServiceProvider myRSACryptoServiceProvider = (RSACryptoServiceProvider)myX509Certificate2.PrivateKey;

 

            //使用RSACryptoServiceProvider把密文字节流解密为明文字节流

            byte[] plaintextByte = myRSACryptoServiceProvider.Decrypt(Cryptograph, false);

 

            //使用加密时采用的同样的代码页utf8把解密后的明文byte[]转成字符串

            string Plaintext = Encoding.UTF8.GetString(plaintextByte);

            return Plaintext;

        }

 

        /// <summary>

        /// 获取信息的Hash值,产生摘要

        /// </summary>

        /// <param name="message">需要哈希的字符串</param>

        /// <returns></returns>

        public byte[] GetHash(string message)

        {

            byte[] messagebytes = Encoding.UTF8.GetBytes(message);

  

            SHA1 sha1 = new SHA1CryptoServiceProvider();

 

            //对要签名的数据进行哈希

            byte[] hashbytes = sha1.ComputeHash(messagebytes);

            return hashbytes;

        }

 

        /// <summary>

        /// 用私钥对哈希值进行签名

        /// </summary>

        /// <param name="hashbytes">哈希值</param>

        /// <returns></returns>

        public byte[] SignByPrivateKey(byte[] hashbytes)

        {

            X509Certificate2 x509 = new X509Certificate2(path + "Certificate//zzServer.p12", "mypassword");

 

            RSAPKCS1SignatureFormatter signe = new RSAPKCS1SignatureFormatter();

 

            //设置签名用到的私钥

            signe.SetKey(x509.PrivateKey);

 

            //设置签名算法

            signe.SetHashAlgorithm("SHA1");

 

            //创建签名

            byte[] signreslut = signe.CreateSignature(hashbytes);

 

            return signreslut;

        }

 

        /// <summary>

        /// 用公钥对签名进行验证

        /// </summary>

        /// <param name="hashbytes">摘要的哈希值</param>

        /// <param name="messagebytes">对哈希值进行签名后的值</param>

        /// <returns></returns>

        public bool VerifySign(byte[] hashbytes, byte[] signreslut)

        {

            // 验签

            X509Certificate2 x509 = new X509Certificate2(path + "Certificate//zzServer.cer", "mypassword");

            RSACryptoServiceProvider oRSA4 = new RSACryptoServiceProvider();

            oRSA4.FromXmlString(x509.PublicKey.Key.ToXmlString(false));

 

            //传入加密的hash数据和签名数据,进行验证

            bool bHash = oRSA4.VerifyHash(hashbytes, "SHA1", signreslut);

            return bHash;

        }

 

以上方法实现了利用公钥加密,私钥解密。以及利用私钥签名,公钥验证的方法。