加密算法之非对称加密RSA

一:非对称加密的由来

RSA公钥加密算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美国麻省理工学院)开发的。RSA取名来自开发他们三者的名字。RSA是目前最有影响力的公钥加密算法,它能够抵抗到目前为止已知的所有密码攻击,已被ISO推荐为公钥数据加密标准。RSA算法基于一个十分简单的数论事实:将两个大素数相乘十分容易,但那时想要对其乘积进行因式分解却极其困难,因此可以将乘积公开作为加密密钥。RSA算法是第一个能同时用于加密和数字签名的算法,也易于理解和操作。

  RSA是被研究得最广泛的公钥算法,从提出到现在已近二十年,经历了各种攻击的考验,逐渐为人们接受,普遍认为是目前最优秀的公钥方案之一。RSA的安全性依赖于大数的因子分解,但并没有从理论上证明破译RSA的难度与大数分解难度等价。即RSA的重大缺陷是无法从理论上把握它的保密性能如何,而且密码学界多数人士倾向于因子分解不是NPC问题。

二:RSA的缺点主要有:

A)产生密钥很麻烦,受到素数产生技术的限制,因而难以做到一次一密。

B)分组长度太大,为保证安全性,n 至少也要 600bits以上,使运算代价很高,尤其是速度较慢,较对称密码算法慢几个数量级;且随着大数分解技术的发展,这个

长度还在增加,不利于数据格式的标准化。目前,SET(Secure Electronic Transaction)协议中要求CA采用2048bits长的密钥,其他实体使用1024比特的密钥。C)RSA密钥长度随着保密级别提高,增加很快。下表列出了对同一安全级别所对应的密钥长度。

保密级别 对称密钥长度(bit) RSA密钥长度(bit) ECC密钥长度(bit) 保密年限
80 80 1024 160 2010
112 112 2048 224 2030
128 128 3072 256 2040
192 192 7680 384 2080
256 256 15360 512 2120

三:算法操作

RSA算法是一种非对称密码算法,所谓非对称,就是指该算法需要一对密钥,使用其中一个加密,则需要用另一个才能解密。

RSA的算法涉及三个参数,n、e1、e2。

其中,n是两个大质数p、q的积,n的二进制表示时所占用的位数,就是所谓的密钥长度。

e1和e2是一对相关的值,e1可以任意取,但要求e1与(p-1)*(q-1)互质;再选择e2,要求(e2*e1)mod((p-1)*(q-1))=1。(n及e1),(n及e2)就是密钥对。

RSA加解密的算法完全相同,设A为明文,B为密文,则:A=B^e1 mod n;B=A^e2 mod n;e1和e2可以互换使用,即:A=B^e2 mod n;B=A^e1 mod n;

四:算法栗子

 //非对称加密
    public class RSAEncrypted
    {

        /// <summary>
        /// RSA产生密钥
        /// </summary>
        public void RSAKey()
        {
            try
            {
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                var xmlKeys = rsa.ToXmlString(true);
                var xmlPublicKey = rsa.ToXmlString(false);
                var str = "明月几时有,把酒问青天,不知道天上今夕是何年";
                //1.1有长度限制的加密
                var cipherText = RSAEncryptLimitLength(xmlPublicKey, str);
                //1.2有长度限制的解密
                var txt = RSADecryptLimitLength(xmlKeys, cipherText);

                //2.1加密
                var cipherText1 = RSAEncrypt(xmlPublicKey, str);
                var txt1 = RSADecrypt(xmlKeys, cipherText1);

                //3.1字符串,hash描述表
                //var hashTxt = GetHashStr(str);
                //3.1文件,hash描述表
                var hashTxt = GetHashFile();

                //3.2进行签名
                var signTxt = SignatureFormatterStr(xmlKeys, hashTxt);
                //3.3签名验证
                var defSign = SignatureDeformatterStr(xmlPublicKey, hashTxt, signTxt);

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 文件,hash描述表
        /// </summary>
        /// <returns></returns>
        public string GetHashFile()
        {
            try
            {
                var path = @"C:\xxx\xxxx\xxx\图解HTTP  上野宣著.pdf";
                FileStream objFile = new FileStream(path, FileMode.Open);
                //从文件中取得Hash描述
                HashAlgorithm MD5 = HashAlgorithm.Create("MD5");
                //返回字节数组
                byte[] HashData = MD5.ComputeHash(objFile);
                objFile.Close();//必须有
                //返回签名字符串
                var result = Convert.ToBase64String(HashData);
                return result;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        #region 字符串的hash描述,签名及验证

        /// <summary>
        /// 字符串,hash描述表
        /// </summary>
        /// <param name="strSource">待签名的字符串</param>
        /// <returns></returns>
        public string GetHashStr(string strSource)
        {
            try
            {
                HashAlgorithm MD5 = HashAlgorithm.Create("MD5");
                byte[] buffer = Encoding.GetEncoding("GB2312").GetBytes(strSource);
                //返回字节数组
                var hashData = MD5.ComputeHash(buffer);
                //返回string
                var hashStr = Convert.ToBase64String(hashData);
                return hashStr;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// RSA签名
        /// </summary>
        /// <param name="strKeyPrivate">私钥</param>
        /// <param name="HashbyteSignature">待签名Hash描述</param>
        /// <returns></returns>
        public string SignatureFormatterStr(string strKeyPrivate, string hashbyteSignatureStr)
        {
            try
            {
                byte[] HashbyteSignature = Convert.FromBase64String(hashbyteSignatureStr);
                byte[] EncryptedSignatureData;
                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                RSA.FromXmlString(strKeyPrivate);
                RSAPKCS1SignatureFormatter RSAFormatter = new RSAPKCS1SignatureFormatter(RSA);
                //设置签名的算法为MD5
                RSAFormatter.SetHashAlgorithm("MD5");
                //执行签名
                //返回字节数据
                EncryptedSignatureData = RSAFormatter.CreateSignature(HashbyteSignature);
                return Convert.ToBase64String(EncryptedSignatureData);

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// RSA签名验证
        /// </summary>
        /// <param name="strKeyPublic">公钥</param>
        /// <param name="strHashbyteDeformatter">Hash描述</param>
        /// <param name="deformatterDataStr">签名后的结果</param>
        /// <returns></returns>
        public bool SignatureDeformatterStr(string strKeyPublic, string strHashbyteDeformatter, string deformatterDataStr)
        {
            try
            {
                byte[] DeformatterData = Convert.FromBase64String(deformatterDataStr);
                byte[] HashbyteDeformatter = Convert.FromBase64String(strHashbyteDeformatter);
                RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
                RSA.FromXmlString(strKeyPublic);
                RSAPKCS1SignatureDeformatter RSADeformatter = new RSAPKCS1SignatureDeformatter(RSA);
                //指定解密的时候HASH算法为MD5
                RSADeformatter.SetHashAlgorithm("MD5");
                if (RSADeformatter.VerifySignature(HashbyteDeformatter, DeformatterData))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
        } 

        #endregion

        #region RSA加密
        /// <summary>
        /// RSA的加密函数
        /// </summary>
        /// <param name="xmlPublicKey">公钥</param>
        /// <param name="encryptString">待加密的字节数组</param>
        /// <returns></returns>
        public string RSAEncrypt(string xmlPublicKey, string encryptString)
        {
            try
            {
                byte[] encrypt = Encoding.Default.GetBytes(encryptString);
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.FromXmlString(xmlPublicKey);
                var cypherTextBArray = rsa.Encrypt(encrypt, false);
                return Convert.ToBase64String(cypherTextBArray);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// RSA的解密函数
        /// </summary>
        /// <param name="xmlPrivateKey">私钥</param>
        /// <param name="decryptString">待解密的字节数组</param>
        /// <returns></returns>
        public string RSADecrypt(string xmlPrivateKey, string decryptString)
        {
            try
            {
                byte[] decrypt = Convert.FromBase64String(decryptString);
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.FromXmlString(xmlPrivateKey);
                var dypherTextBArray = rsa.Decrypt(decrypt, false);
                // return (new UnicodeEncoding()).GetString(dypherTextBArray);
                return Encoding.Default.GetString(dypherTextBArray);

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

        #region RSA加密,有长度限制
        /// <summary>
        /// RSA的加密函数,该加密方式有长度限制的
        /// </summary>
        /// <param name="xmlPublicKey">公钥</param>
        /// <param name="encryptString">待加密的字符串</param>
        /// <returns></returns>
        public string RSAEncryptLimitLength(string xmlPublicKey, string encryptString)
        {
            try
            {
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.FromXmlString(xmlPublicKey);
                byte[] plainTextBArray = (new UnicodeEncoding()).GetBytes(encryptString);
                byte[] cypherTextBArray = rsa.Encrypt(plainTextBArray, false);
                return Convert.ToBase64String(cypherTextBArray);

            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// RSA的解密函数
        /// </summary>
        /// <param name="xmlPrivateKey">私钥</param>
        /// <param name="decryptString">待解密的字符串</param>
        /// <returns></returns>
        public string RSADecryptLimitLength(string xmlPrivateKey, string decryptString)
        {
            try
            {
                RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
                rsa.FromXmlString(xmlPrivateKey);
                byte[] plainTextBArray = Convert.FromBase64String(decryptString);
                byte[] dypherTextBArray = rsa.Decrypt(plainTextBArray, false);
                return (new UnicodeEncoding()).GetString(dypherTextBArray);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        #endregion

    }

文章参考:http://www.cnblogs.com/linzheng/archive/2011/02/20/1959123.html

http://www.cnblogs.com/sydeveloper/archive/2012/08/11/2633624.html

时间: 2024-12-11 01:38:47

加密算法之非对称加密RSA的相关文章

Crypto++应用:非对称加密RSA

1,非对称加密RSA: (1)乙方生成两把密钥(公钥和私钥).公钥是公开的,任何人都可以获得,私钥则是保密的. (2)甲方获取乙方的公钥,然后用它对信息加密. (3)乙方得到加密后的信息,用私钥解密. 2,使用CryptoPP实现RSA: CryptoPP是一套非常完整的加密解密开源解决方案,如何使用这里就不多说了,请自行Google. #include "..\cryptopp562\randpool.h" #include "..\cryptopp562\osrng.h&

非对称加密RSA的应用及在C#中的实现

quote: http://www.cnblogs.com/happinessCodes/archive/2010/07/27/1786404.html 一说到数据的加密,常常会涉及到这几个单词:算法.原文.密文和密钥.通常,发送者把原文通过一个加密的算法,用密钥进行加密后将密文发送给接收者,然后接收者再用密钥对密文进行解密,得到原文.由于常用的加密算法都是公开的,所以,对原文的加密的关键,就是密钥了.对于这种加解密都使用同样的密钥的算法,我们称之为对称加密,对称加密的代表算法就是DES家族了.

非对称加密RSA的C#实现

1.对称加密算法 对称加密是最快速.最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key). 对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中.对称加密通常使用的是相对较小的密钥, 一般小于256 bit.因为密钥越大,加密越强,但加密与解密的过程越慢.如果你只用1 bit来做这个密钥,那黑客们可以先试着用0来解密, 不行的话就再用1解:但如果你的密钥有1 MB大,黑客们可能永远也无法破解,但加密和解密

非对称加密RSA加密文件

RSA加密文件 关于RSA非对称加密很多地方都有讲解. 下面是AES AES 类 import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.security.Key; import java.security.SecureRandom; impor

java 非对称加密RSA

package com.aarony.test; import java.io.IOException; import java.security.KeyFactory; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.sec

非对称加密——RSA算法工具类

关于RSA算法的介绍网上一大堆,一句话就是牛B. package com.demo; import org.springframework.util.StringUtils; import javax.crypto.Cipher; import java.security.*; import java.security.interfaces.RSAPrivateKey; import java.security.interfaces.RSAPublicKey; import java.secur

https 结合使用 对称加密和非对称加密

(一)对称加密(Symmetric Cryptography) ---共享密钥加密 对称加密是最快速.最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key),这种方法在密码学中叫做对称加密算法.对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中.对称加密通常使用的是相对较小的密钥,一般小于256 bit.因为密钥越大,加密越强,但加密与解密的过程越慢.如果你只用1 bit来做这个密钥,那黑客们可以先试着用

白话数字签名(1)——基本原理(新!) 对称加密 非对称加密 数字签名

http://www.cnblogs.com/1-2-3/archive/2007/09/17/colloquialism-digital-certificate-part1.html 摘要 本系列通过通俗易懂的讲解,让您就像读小说一般,轻轻松松就能理解数字签名的基本原理和应用方法(即使您是一个并不精通计算机的企业老总,也能读懂本篇文章).然后我们再逐步深入技术细节,最后将给出一个在B/S信息系统中使用数字签名的DEMO. 由于数字签名基于非对称加密技术,所以我们需要先啰嗦一下对称加密和非对称加

非对称加密和对称加密的区别

在了解对称加密和非对称加密的区别之前我们先了解一下它们的定义: 对称加密(Symmetric Cryptography),又称私钥加密 对称加密是最快速.最简单的一种加密方式,加密(encryption)与解密(decryption)用的是同样的密钥(secret key),这种方法在密码学中叫做对称加密算法.对称加密有很多种算法,由于它效率很高,所以被广泛使用在很多加密协议的核心当中.对称加密通常使用的是相对较小的密钥,一般小于256 bit.因为密钥越大,加密越强,但加密与解密的过程越慢.如