zoukankan      html  css  js  c++  java
  • 【.NET Core】RSA算法前端及后端加密实现

    前言

    非对称加密算法的优缺点就不赘述了,目前使用最广泛的就是RSA算法,而在Web项目中一些关键信息肯定是不能明文传输的,最简单的就是用户密码。
    而.NET下的RSA类所生成的密钥为Xml格式,而其他语言比如java一般使用pkcs8格式的密钥,前端JavaScript一般使用pkcs1格式。格式不同导致后端密钥无法被前端使用,我们就得想办法统一key进行加解密,下面是我总结的解决方案(我只是一个总结者,下面内容来源于博客园多个前辈,只是当时没有记录来源,写文时没法贴上链接)

    正文

    后端

    使用类库:“BouncyCastle.NetCore”(.Net FrameWork使用“BouncyCastle”)

    using System;
    using System.IO;
    using System.Text;
    using Org.BouncyCastle.Crypto;
    using Org.BouncyCastle.Crypto.Encodings;
    using Org.BouncyCastle.Crypto.Engines;
    using Org.BouncyCastle.Crypto.Generators;
    using Org.BouncyCastle.OpenSsl;
    using Org.BouncyCastle.Security;
    
    namespace Utility
    {
        /// <summary>
        /// RAS非对称算法
        /// </summary>
        public class RSAUtility
        {
            /// <summary>
            /// 生成PEM格式的公钥和密钥
            /// </summary>
            /// <param name="strength">长度</param>
            /// <returns>Item1:公钥;Item2:私钥;</returns>
            public static (string, string) CreateKeyPair(int strength = 1024)
            {
                RsaKeyPairGenerator r = new RsaKeyPairGenerator();
                r.Init(new KeyGenerationParameters(new SecureRandom(), strength));
                AsymmetricCipherKeyPair keys = r.GenerateKeyPair();
    
                TextWriter privateTextWriter = new StringWriter();
                PemWriter privatePemWriter = new PemWriter(privateTextWriter);
                privatePemWriter.WriteObject(keys.Private);
                privatePemWriter.Writer.Flush();
    
    
                TextWriter publicTextWriter = new StringWriter();
                PemWriter publicPemWriter = new PemWriter(publicTextWriter);
                publicPemWriter.WriteObject(keys.Public);
                publicPemWriter.Writer.Flush();
    
    
                return (publicTextWriter.ToString(), privateTextWriter.ToString());
            }
    
            /// <summary>
            /// RSA解密
            /// </summary>
            /// <param name="privateKey">私钥</param>
            /// <param name="decryptstring">待解密的字符串(Base64)</param>
            /// <returns>解密后的字符串</returns>
            public static string Decrypt(string privateKey, string decryptstring)
            {
                using (TextReader reader = new StringReader(privateKey))
                {
                    dynamic key = new PemReader(reader).ReadObject();
                    var rsaDecrypt = new Pkcs1Encoding(new RsaEngine());
                    if (key is AsymmetricKeyParameter)
                    {
                        key = (AsymmetricKeyParameter)key;
                    }
                    else if (key is AsymmetricCipherKeyPair)
                    {
                        key = ((AsymmetricCipherKeyPair)key).Private;
                    }
                    rsaDecrypt.Init(false, key);  //这里加密是true;解密是false  
    
                    byte[] entData = Convert.FromBase64String(decryptstring);
                    entData = rsaDecrypt.ProcessBlock(entData, 0, entData.Length);
                    return Encoding.UTF8.GetString(entData);
                }
            }/// <summary>
    
             /// 加密
             /// </summary>
             /// <param name="publicKey">公钥</param>
             /// <param name="encryptstring">待加密的字符串</param>
             /// <returns>加密后的Base64</returns>
            public static string Encrypt(string publicKey, string encryptstring)
            {
                using (TextReader reader = new StringReader(publicKey))
                {
                    AsymmetricKeyParameter key = new PemReader(reader).ReadObject() as AsymmetricKeyParameter;
                    Pkcs1Encoding pkcs1 = new Pkcs1Encoding(new RsaEngine());
                    pkcs1.Init(true, key);//加密是true;解密是false;
                    byte[] entData = Encoding.UTF8.GetBytes(encryptstring);
                    entData = pkcs1.ProcessBlock(entData, 0, entData.Length);
                    return Convert.ToBase64String(entData);
                }
            }
        }
    }
    

    如果想私钥加密,公钥解密可以引用类库:“BouncyCastle.Crypto”,参考地址如下:
    https://www.cnblogs.com/dj258/p/6049786.html

    前端

    前端引用jsencrypt.js

    /*
     * RSA算法加密
     * key:公钥
     * encryptstring:待加密信息
     */
    function RSAEncryption(key, encryptstring) {
                //rsa加密随机密钥
                var rsa = new JSEncrypt();
                //设置后端接口传回的公钥(无需对公钥字符串做任何处理)
                rsa.setPublicKey(key);
    
                //注意:RSA加解密有大小限制(最多117 bytes)
                var rsaEncrypted = rsa.encrypt(encryptstring);
    
                //已加密的字符串(Base64)
                return rsaEncrypted;
            }
    

    PEM格式存在换行,因此建议把公钥放在隐藏域中:

    <input id="encryption" name="encryption" type="hidden" value="@ViewData["publicKey"]">
    
  • 相关阅读:
    团体程序设计天梯赛PTA L1-006连续因子
    团体程序设计天梯赛PTA L1-002打印沙漏
    spring学习3-配置文件
    markdown基本用法
    java贪食蛇小游戏
    在idea中使用lombook插件
    ajax初体验hello_ajax
    idea,自定义骨架的增加与删除
    idea 2017,2018,2019下载与破解
    idea关联mysql数据库失败,时区错误,数据库驱动配置
  • 原文地址:https://www.cnblogs.com/NBDWDYS2214143926/p/13329231.html
Copyright © 2011-2022 走看看