博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 加密–RSA前端与后台的加密&解密
阅读量:5816 次
发布时间:2019-06-18

本文共 10327 字,大约阅读时间需要 34 分钟。

1. 前言

本问是根据网上很多文章的总结得到的。

 

2. 介绍

  RSA加密算法是一种非对称加密算法。

  对极大整数做因数分解的难度决定了RSA算法的可靠性。换言之,对一极大整数做因数分解愈困难,RSA算法愈可靠。假如有人找到一种快速因数分解的算法的话,那么用RSA加密的信息的可靠性就肯定会极度下降。但找到这样的算法的可能性是非常小的。今天只有短的RSA钥匙才可能被强力方式解破。到2016年为止,世界上还没有任何可靠的攻击RSA算法的方式。只要其钥匙的长度足够长,用RSA加密的信息实际上是不能被解破的。

  1983年麻省理工学院在美国为RSA算法申请了专利。这个专利2000年9月21日失效。由于该算法在申请专利前就已经被发表了,在世界上大多数其它地区这个专利权不被承认。

具体介绍可以查看维基百科

 

3. 开始

1)在线RSA加密,请选用PKCS#1来生成公钥与私钥

点击【生成秘钥对RSA】就可以生成对应的非对称加密公钥与非对称加密似钥

2)前端JS框架

3)流程图

从上图可以看到,先从网站上生成publicKey与privateKey。

第一步返回publicKey前端,用来对password等敏感字段的加密。

第二步,前端进行password敏感字段的加密。

第三步post数据给后端。

第四步用publicKey与privateKey进行解密。

 

4.代码

这里的代码是简单的直接从前端访问后台,后台进行解密。逻辑根据读者的爱好编写。

前端代码

    
name:
password:

 

后端代码

解密

private RSACrypto rsaCrypto = new RSACrypto(PublicAttribute.PrivateKey, PublicAttribute.PublicKey);//获取参数 string usernameEncode = Request["username"]; string pwdEncode = Request["pwd"];//解密 RSA string username = rsaCrypto.Decrypt(usernameEncode); string pwd = rsaCrypto.Decrypt(pwdEncode);

类 RSACrypto

public class RSACrypto    {        private RSACryptoServiceProvider _privateKeyRsaProvider;        private RSACryptoServiceProvider _publicKeyRsaProvider;        public RSACrypto(string privateKey, string publicKey = null)        {            if (!string.IsNullOrEmpty(privateKey))            {                _privateKeyRsaProvider = CreateRsaProviderFromPrivateKey(privateKey);            }            if (!string.IsNullOrEmpty(publicKey))            {                _publicKeyRsaProvider = CreateRsaProviderFromPublicKey(publicKey);            }        }        public string Decrypt(string cipherText)        {            if (_privateKeyRsaProvider == null)            {                throw new Exception("_privateKeyRsaProvider is null");            }            return Encoding.UTF8.GetString(_privateKeyRsaProvider.Decrypt(System.Convert.FromBase64String(cipherText), false));        }        public string Encrypt(string text)        {            if (_publicKeyRsaProvider == null)            {                throw new Exception("_publicKeyRsaProvider is null");            }            return Convert.ToBase64String(_publicKeyRsaProvider.Encrypt(Encoding.UTF8.GetBytes(text), false));        }        private RSACryptoServiceProvider CreateRsaProviderFromPrivateKey(string privateKey)        {            var privateKeyBits = System.Convert.FromBase64String(privateKey);            var RSA = new RSACryptoServiceProvider();            var RSAparams = new RSAParameters();            using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits)))            {                byte bt = 0;                ushort twobytes = 0;                twobytes = binr.ReadUInt16();                if (twobytes == 0x8130)                    binr.ReadByte();                else if (twobytes == 0x8230)                    binr.ReadInt16();                else                    throw new Exception("Unexpected value read binr.ReadUInt16()");                twobytes = binr.ReadUInt16();                if (twobytes != 0x0102)                    throw new Exception("Unexpected version");                bt = binr.ReadByte();                if (bt != 0x00)                    throw new Exception("Unexpected value read binr.ReadByte()");                RSAparams.Modulus = binr.ReadBytes(GetIntegerSize(binr));                RSAparams.Exponent = binr.ReadBytes(GetIntegerSize(binr));                RSAparams.D = binr.ReadBytes(GetIntegerSize(binr));                RSAparams.P = binr.ReadBytes(GetIntegerSize(binr));                RSAparams.Q = binr.ReadBytes(GetIntegerSize(binr));                RSAparams.DP = binr.ReadBytes(GetIntegerSize(binr));                RSAparams.DQ = binr.ReadBytes(GetIntegerSize(binr));                RSAparams.InverseQ = binr.ReadBytes(GetIntegerSize(binr));            }            RSA.ImportParameters(RSAparams);            return RSA;        }        private int GetIntegerSize(BinaryReader binr)        {            byte bt = 0;            byte lowbyte = 0x00;            byte highbyte = 0x00;            int count = 0;            bt = binr.ReadByte();            if (bt != 0x02)                return 0;            bt = binr.ReadByte();            if (bt == 0x81)                count = binr.ReadByte();            else                if (bt == 0x82)            {                highbyte = binr.ReadByte();                lowbyte = binr.ReadByte();                byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };                count = BitConverter.ToInt32(modint, 0);            }            else            {                count = bt;            }            while (binr.ReadByte() == 0x00)            {                count -= 1;            }            binr.BaseStream.Seek(-1, SeekOrigin.Current);            return count;        }        private RSACryptoServiceProvider CreateRsaProviderFromPublicKey(string publicKeyString)        {            // encoded OID sequence for  PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1"            byte[] SeqOID = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 };            byte[] x509key;            byte[] seq = new byte[15];            int x509size;            x509key = Convert.FromBase64String(publicKeyString);            x509size = x509key.Length;            // ---------  Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob  ------            using (MemoryStream mem = new MemoryStream(x509key))            {                using (BinaryReader binr = new BinaryReader(mem))  //wrap Memory Stream with BinaryReader for easy reading                {                    byte bt = 0;                    ushort twobytes = 0;                    twobytes = binr.ReadUInt16();                    if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)                        binr.ReadByte();    //advance 1 byte                    else if (twobytes == 0x8230)                        binr.ReadInt16();   //advance 2 bytes                    else                        return null;                    seq = binr.ReadBytes(15);       //read the Sequence OID                    if (!CompareBytearrays(seq, SeqOID))    //make sure Sequence for OID is correct                        return null;                    twobytes = binr.ReadUInt16();                    if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81)                        binr.ReadByte();    //advance 1 byte                    else if (twobytes == 0x8203)                        binr.ReadInt16();   //advance 2 bytes                    else                        return null;                    bt = binr.ReadByte();                    if (bt != 0x00)     //expect null byte next                        return null;                    twobytes = binr.ReadUInt16();                    if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81)                        binr.ReadByte();    //advance 1 byte                    else if (twobytes == 0x8230)                        binr.ReadInt16();   //advance 2 bytes                    else                        return null;                    twobytes = binr.ReadUInt16();                    byte lowbyte = 0x00;                    byte highbyte = 0x00;                    if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81)                        lowbyte = binr.ReadByte();  // read next bytes which is bytes in modulus                    else if (twobytes == 0x8202)                    {                        highbyte = binr.ReadByte(); //advance 2 bytes                        lowbyte = binr.ReadByte();                    }                    else                        return null;                    byte[] modint = { lowbyte, highbyte, 0x00, 0x00 };   //reverse byte order since asn.1 key uses big endian order                    int modsize = BitConverter.ToInt32(modint, 0);                    int firstbyte = binr.PeekChar();                    if (firstbyte == 0x00)                    {   //if first byte (highest order) of modulus is zero, don't include it                        binr.ReadByte();    //skip this null byte                        modsize -= 1;   //reduce modulus buffer size by 1                    }                    byte[] modulus = binr.ReadBytes(modsize);   //read the modulus bytes                    if (binr.ReadByte() != 0x02)            //expect an Integer for the exponent data                        return null;                    int expbytes = (int)binr.ReadByte();        // should only need one byte for actual exponent data (for all useful values)                    byte[] exponent = binr.ReadBytes(expbytes);                    // ------- create RSACryptoServiceProvider instance and initialize with public key -----                    RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();                    RSAParameters RSAKeyInfo = new RSAParameters();                    RSAKeyInfo.Modulus = modulus;                    RSAKeyInfo.Exponent = exponent;                    RSA.ImportParameters(RSAKeyInfo);                    return RSA;                }            }        }        private bool CompareBytearrays(byte[] a, byte[] b)        {            if (a.Length != b.Length)                return false;            int i = 0;            foreach (byte c in a)            {                if (c != b[i])                    return false;                i++;            }            return true;        }    }

 

到此结束了。

 

 

可以关注本人的公众号,多年经验的原创文章共享给大家。

posted on
2016-08-10 21:06 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/alunchen/p/5758585.html

你可能感兴趣的文章
Using RequireJS in AngularJS Applications
查看>>
hdu 2444(二分图最大匹配)
查看>>
shell编程笔记六:实现ll命令
查看>>
【SAP HANA】关于SAP HANA中带层次结构的计算视图Cacultation View创建、激活状况下在系统中生成对象的研究...
查看>>
[nodejs] nodejs开发个人博客(五)分配数据
查看>>
《Linux内核修炼之道》 之 高效学习Linux内核
查看>>
Java数据持久层框架 MyBatis之API学习九(SQL语句构建器详解)
查看>>
30分钟Git命令“从入门到放弃”
查看>>
nginx : TCP代理和负载均衡的stream模块
查看>>
MYSQL数据库间同步数据
查看>>
DevOps 前世今生 | mPaaS 线上直播 CodeHub #1 回顾
查看>>
iOS 解决UITabelView刷新闪动
查看>>
让前端小姐姐愉快地开发表单
查看>>
Dubbo笔记(四)
查看>>
Web前端JQuery入门实战案例
查看>>
java B2B2C Springboot电子商城系统- SSO单点登录之OAuth2.0 登出流程(3)
查看>>
USB 通信原理
查看>>
7zZip zip RAR iOS
查看>>
date命令的详细用法!
查看>>
UiAutomator源码分析之UiAutomatorBridge框架
查看>>