RSA加密
非对称加密算法,两个且不同的Key,一个公开,一个私密,公开加密,私密解密。
特点:
原文短,加密后密文长
生成相对较慢
安全性超强
生成公钥、私钥
我们使用.net进行生成公钥、私钥。
使用RSA.ToXmlString(Boolean) 方法生成公钥以及私钥,方法中接收一个参数,true
表示同时包含 RSA 公钥和私钥;false
表示仅包含公钥,需要注意的是这里生成的是XML格式。
RSACryptoServiceProvider rSA = new();string pubKey = rSA.ToXmlString(false);//公钥string priKey = rSA.ToXmlString(true);//私钥
后端使用
在后端加密解密需要引入RSACryptoServiceProvider 类,该类提供了对RSA算法的实现执行非对称加密和解密,同时,该类是不可被继承的。
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
RSA加密
加密调用Encrypt(Byte[], Boolean)方法,第一个参数为需要加密的数据,是一个byte[]格式,返回同样为一个byte[]格式。
byte[] cipherbytes;rsa.FromXmlString(pubKey);cipherbytes = rsa.Encrypt(Encoding.UTF8.GetBytes(source), false);var b = Convert.ToBase64String(cipherbytes);
RSA解密
解密调用Decrypt(Byte[], Boolean)方法,第一个参数为要解密的数据,是一个byte[]格式,返回同样为一个byte[]格式。
rsa.FromXmlString(priKey);byte[] cipherbytex;cipherbytex = rsa.Decrypt(Convert.FromBase64String(b), false);var c = Encoding.UTF8.GetString(cipherbytex);
前端vue使用后端传递的公钥加密
我这里使用的加密库为JSEncrypt库,安装JSEncrypt库。
npm install jsencrypt -D
在页面中对其引用。
import {JSEncrypt} from 'jsencrypt'
需要注意 :.net生成的公钥与私钥是XML格式,而前端JSEncrypt库使用时需要Pkcs8格式,我们这里需要在后端处理一下公钥再传递给前端,不然前端返回密文的时候为falae。
后端将XML格式转换为Pkcs8格式
我们需要在程序包管理控制台中安装XC.RSAUtil包
NuGet\Install-Package XC.RSAUtil -Version 1.3.6
这个包包含了几种转换的格式:
XML转Pkcs1
RsaKeyConvert.PrivateKeyXmlToPkcs1()私钥
RsaKeyConvert.PublicKeyXmlToPem()公钥
XML转Pkcs8
RsaKeyConvert.PrivateKeyXmlToPkcs8()私钥
RsaKeyConvert.PublicKeyXmlToPem()公钥
Pkcs1转XML
RsaKeyConvert.PrivateKeyPkcs1ToXml()私钥
RsaKeyConvert.PublicKeyPemToXml()公钥
Pkcs8转XML
RsaKeyConvert.PrivateKeyPkcs8ToXml()私钥
RsaKeyConvert.PublicKeyPemToXml()公钥
我这里使用RsaKeyConvert.PublicKeyXmlToPem() ,再将转换的值传递给前端,前端就能使用JSEncrypt进行RSA加密了。
string pubKey = rSA.ToXmlString(false);//公钥string priKey = rSA.ToXmlString(true);//私钥var keyList = RsaKeyConvert.PublicKeyXmlToPem(pubKey);//将xml格式转换为Pkcs8return new { keyList };
前端加密
虽然我们前端是可以解密的,但是处于安全考虑,我们只用将公钥传递给前端就可以了,私钥是不传递的,私钥是用于解码使用公钥加密的密文。
我们使用JSEncrypt库主要使用其中的几个方法:
setPublicKey('获取的公钥')设置公钥
setPrivateKey('获取的私钥')设置私钥
encrypt('加密内容')加密
decrypt('解密内容')解密
这里我们使用公钥对对456进行加密。
postFdd().then(res => {console.log(res)var encryptor = new JSEncrypt()encryptor.setPublicKey(res.keyList)var rsaPassWord = encryptor.encrypt('456')// encryptor.setPrivateKey(res.priKey) //设置秘钥// var uncrypted = decrypt.decrypt(encryptor) //解密之前拿公钥加密的内容console.log(rsaPassWord)})
我们打印出来可以看到 keyList是为Pkcs8格式,priKey是为XML格式,而下面那一段字段就是我们加密出来的密文。
XML的格式以及Pkcs8格式
XML开头为<RSAKeyValue><Modulus>
Pkcs8格式开头为-----BEGIN PUBLIC KEY-----