zoukankan      html  css  js  c++  java
  • 加密算法之非对称加密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:xxxxxxxxxx图解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

  • 相关阅读:
    iOS sandbox
    属性和成员变量
    SDWebImage
    MRC和ARC混编
    MRC转ARC(2)
    MRC转ARC
    CentOS7.x关闭防火墙
    Linux下Tomcat带日志启动命令
    SpringBoot-属性文件properties形式
    SpringBoot-配置Java方式
  • 原文地址:https://www.cnblogs.com/xiaoyaodijun/p/6549148.html
Copyright © 2011-2022 走看看