最近公司项目验收后,客户请来的信息安全技术人员对我们的网站进行了各种安全测试与排查问题,其中就有一个登陆时的加密问题。本来如果只是单纯的加密,可以直接在前台用MD5加密,将加密的值添加到数据库即可。但是现在的项目里有很多的用户,密码也是后台MD5加密了的。这样就不能单纯在前台用MD5加密,可能是本人能力有限,使用的前台MD5加密与后台的MD5加密的值不一致,用户登陆在密码比对的时候就会失败登陆不了。只能使用非对称加密,前台加密后台解密后使用MD5加密再作对比,这种做法才能使用改动最少。网上查资料后就使用了RSA非对称加密。

https://www.cnblogs.com/amylis_chen/p/6054414.html

前端代码

<script src="http://code.jquery.com/jquery-1.8.3.min.js"></script>

<script src="http://passport.cnblogs.com/scripts/jsencrypt.min.js"></script>

<script>

   var encrypt = new JSEncrypt();

    encrypt.setPublicKey("公钥可以用工具生成");
    var userPwd = encrypt.encrypt(输入的密码);     //加密后的密码

</script>

后端代码

var publicKey = "公钥可以用工具生成"

var privateKey = "私钥可以用工具生成“

RSACrypto rsaCrypto = new RSACrypto(privateKey, publicKey);
userPwd = rsaCrypto.Decrypt(userPwd);    //解密后的密码,就是输入密码的值

/// <summary>
/// RSA非对称加密
/// </summary>
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;
}
}

RSA密钥对生成工具---------http://web.chacuo.net/netrsakeypair

请选用PKCS#1来生成公钥与私钥

RSA 登陆加密与解密的更多相关文章

  1. 密码疑云 (3)——详解RSA的加密与解密

    上一篇文章介绍了RSA涉及的数学知识,本章将应用这些知识详解RSA的加密与解密. RSA算法的密钥生成过程 密钥的生成是RSA算法的核心,它的密钥对生成过程如下: 1. 选择两个不相等的大素数p和q, ...

  2. polarssl rsa & aes 加密与解密

    上周折腾加密与解密,用了openssl, crypto++, polarssl, cyassl, 说起真的让人很沮丧,只有openssl & polarssl两个库的RSA & AES ...

  3. RSA前台加密后台解密的应用

    写在前面 项目安全测试需要将登录功能修改, AES加密不符合要求, 现改为RSA非对称加密.(将登录密码加密后传给后台, 后台解密后再进行一系列的校验) .期间遇到了前台js加密但是后台解密失败的问题 ...

  4. polarssl rsa & aes 加密与解密<转>

    上周折腾加密与解密,用了openssl, crypto++, polarssl, cyassl, 说起真的让人很沮丧,只有openssl & polarssl两个库的RSA & AES ...

  5. 求求你们不要再用 RSA 私钥加密公钥解密了,这非常不安全!

    最近经常在网上看到有人说巨硬的 CNG(Cryptography Next Generation 即下一代加密技术) 只提供 RSA 公钥加密私钥解密,没有提供 RSA 私钥加密公钥解密,他们要自己封 ...

  6. 银联手机支付(.Net Csharp),3DES加密解密,RSA加密解密,RSA私钥加密公钥解密,.Net RSA 3DES C#

    前段时间做的银联支付,折腾了好久,拼凑的一些代码,有需要的朋友可以参考,本人.Net新手,不保证准确性! 这个银联手机支付没有SDK提供,技术支持也没有.Net的,真心不好搞! RSA加解密,这里有个 ...

  7. RSA javascript加密 lua解密

    一个在线RSA非对称加密解密,可以用这个地址生成公钥和私钥 https://blog.zhengxianjun.com/online-tool/rsa/ javascript加密 jsencrypt. ...

  8. RSA js加密 java解密

    1. 首先你要拥有一对公钥.私钥: ``` pubKeyStr = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC1gr+rIfYlaNUNLiFsK/Kn ...

  9. RSA der加密 p12解密以及配合AES使用详解

    在前面的文章中我有说过AES和RSA这两种加密方式,正好在前段时间再项目中有使用到,在这里再把这两种加密方式综合在一起写一下,具体到他们的使用,以及RSA各种加密文件的生成. 一: RSA各种加密相关 ...

随机推荐

  1. dedecmsV5.7 调用其他站点的数据库的数据的方法

    问题:网站是用dedecmsv5.7写的,后来加了一套论坛discuzX3.4.因为dede要调用dz的数据,本来用jsonp跨域请求的数据,但是m端掉用的时候会把请求的链接的域名后面自动加个/m(不 ...

  2. Linux下使用 github+hexo 搭建个人博客07-next主题接入搜索和站点管理

    这是搭建个人博客系统系列文章的最后一篇,如果你是从第一篇一路跟下来的,那么恭喜你,即将完成整个博客网站的搭建.OK,话不多说,开始我们的收官之战. 不知你想过没有,如果我们的文章少,一眼看完整个目录, ...

  3. Centos下,Docker部署Yapi接口管理平台

    前言介绍 Yapi 由 YMFE 开源,旨在为开发.产品.测试人员提供更优雅的接口管理服务,可以帮助开发者轻松创建.发布.维护 API. 项目地址:https://github.com/YMFE/ya ...

  4. Linux-3.14.12内存管理笔记【构建内存管理框架(2)】

    前面构建内存管理框架,已经将内存管理node节点设置完毕,接下来将是管理区和页面管理的构建.此处代码实现主要在于setup_arch()下的一处钩子:x86_init.paging.pagetable ...

  5. 解决问题:Red Hat Enterprise Linux 7 64 位 虚拟机安装后无法启动图形化

    原因: 1.系统在创建时,没有安装图形化 2.系统在安装后,有降低内存的操作,内存过低无法启动桌面,以及其他 就原因一进行图形化安装: 1.VMware挂载Red Hat Enterprise Lin ...

  6. Leetcode450. 删除二叉搜索树中的节点

    思路: (1)如果root为空,返回 (2)如果当前结点root是待删除结点: a:root是叶子结点,直接删去即可 b:root左子树不为空,则找到左子树的最大值,即前驱结点,使用前驱结点代替待删除 ...

  7. 通过windows组策略配置时间同步

    Windows系统中带有NTP服务器和客户端的程序,只需在Windows中简单配置即可实现电脑之间的时间同步. 网上常见的配置NTP服务器的方法是修改系统注册表,这种方法是微软不推荐的.在实际使用中, ...

  8. CF1269A Equation

    题目链接 题意 要找两个合数,使他们两个的差为\(n\),\(n\)为题目给出的数 思路 我们可以枚举减数\(now\),判断一下是不是质数,如果是质数就让\(now++\),然后用一个数\(tot\ ...

  9. electron窗口间通信

    以下代码均来自于我开发的开源软件:想学吗 窗口A的渲染进程发消息给主进程 const { clipboard, ipcRenderer, remote } = require('electron'); ...

  10. vue--npm install只许成功,不许失败

    npm安装时出现run `npm audit fix` to fix them, or `npm audit` for details 方案一: 1.如果你的项目里存在 package-lock.js ...