[Note] back-end first: OpenSSL RSA-based encryption keys to decrypt the next .NET Core (cross-platform)

Generating a key using OpenSSL:

# 生成密钥Pkcs1
openssl genrsa -out private.pem 2048

# 生成公钥Pkcs8
openssl rsa -in private.pem -pubout -out public.pem

# 公钥Pkcs8转Pkcs1
openssl rsa -pubin -in public.pem -RSAPublicKey_out

The following classes using the encryption key and a public key Pkcs1, as follows:

using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Encrypt
{
    /// <summary>
    /// RSA加密算法(验签部分还没加入)
    /// </summary>
    public class RSAHelper
    {
        private RSA rsa;

        /// <summary>
        /// 公钥
        /// </summary>
        public string PubKey { get; private set; }

        /// <summary>
        /// 私钥
        /// </summary>
        public string PrivKey { get; private set; }

        public RSAHelper(string privKey, string pubKey)
        {
            this.PrivKey = privKey;
            this.PubKey = pubKey;

        }

        /// <summary>
        /// 读取密钥参数
        /// </summary>
        /// <param name="ms"></param>
        /// <returns></returns>
        public byte[] ReadParaItem(MemoryStream ms)
        {
            if (ms.ReadByte() == 0x02)
            {
                int len = 0;
                byte tmpByte = (byte)ms.ReadByte();
                if (tmpByte == 0x81)//数据
                {
                    byte[] tmpBytes = new byte[1];
                    ms.Read(tmpBytes, 0, 1);
                    //长度
                    len = tmpBytes[0];
                }
                else if (tmpByte == 0x82)//数据
                {
                    byte[] tmpBytes = new byte[2];
                    ms.Read(tmpBytes, 0, 2);
                    //长度
                    len = (tmpBytes[0] << 8) + tmpBytes[1];
                }
                else
                {
                    throw new Exception("异常格式");
                }
                bool isPadding = true;//去掉开头00填充
                List<byte> resultBytes = new List<byte>();
                for (int i = 0; i < len; i++)
                {
                    byte[] tmpBytes = new byte[1];
                    if (ms.Read(tmpBytes, 0, 1) > 0)
                    {
                        if (isPadding && tmpBytes[0] == 0x00)
                        {
                            continue;
                        }
                        else
                        {
                            isPadding = false;
                            resultBytes.AddRange(tmpBytes);
                        }
                    }
                    else
                    {
                        throw new Exception("长度异常");
                    }
                }
                return resultBytes.ToArray();
            }
            else
            {
                return null;
            }
        }

        /// <summary>
        /// 解析Pkcs1密钥
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public RSAParameters CreateRSAParameters(string key)
        {
            RSAParameters parameters = new RSAParameters();
            //解码密钥
            byte[] keyBytes = Convert.FromBase64String(key);
            //判断是否公钥
            bool isPubKey = false;
            if (keyBytes[1] == 0x81 && (keyBytes[4] == 0x81 || keyBytes[4] == 0x82))
            {
                isPubKey = true;
            }
            else if (keyBytes[1] == 0x82 && (keyBytes[5] == 0x81 || keyBytes[5] == 0x82))
            {
                isPubKey = true;
            }
            using (var ms = new MemoryStream(keyBytes))
            {
                int len = 0;
                byte[] headBytes = new byte[2];
                ms.Read(headBytes, 0, 2);
                if (headBytes[0] == 0x30 && headBytes[1] == 0x81)
                {
                    byte[] tmpBytes = new byte[1];
                    ms.Read(tmpBytes, 0, 1);
                    //总长度
                    len = tmpBytes[0];
                }
                else if (headBytes[0] == 0x30 && headBytes[1] == 0x82)
                {
                    byte[] tmpBytes = new byte[2];
                    ms.Read(tmpBytes, 0, 2);
                    //总长度
                    len = (tmpBytes[0] << 8) + tmpBytes[1];
                }
                else
                {
                    throw new Exception("异常开头");
                }
                //私钥参数
                if (isPubKey == false)
                {
                    //版本号,versionBytes[2]==0(标准密钥),versionBytes[2]==1(含多个参数)
                    byte[] versionBytes = new byte[3];
                    ms.Read(versionBytes, 0, 3);
                }

                //读取Modulus
                parameters.Modulus = ReadParaItem(ms);
                //读取Exponent
                if (ms.ReadByte() == 0x02)
                {
                    byte[] tmpBytes = new byte[1];
                    ms.Read(tmpBytes, 0, 1);
                    //长度
                    len = tmpBytes[0];
                    parameters.Exponent = new byte[len];
                    ms.Read(parameters.Exponent, 0, len);
                }
                //私钥参数
                if (isPubKey == false)
                {
                    //读取D
                    parameters.D = ReadParaItem(ms);
                    //读取P
                    parameters.P = ReadParaItem(ms);
                    //读取Q
                    parameters.Q = ReadParaItem(ms);
                    //读取DP
                    parameters.DP = ReadParaItem(ms);
                    //读取DQ
                    parameters.DQ = ReadParaItem(ms);
                    //读取InverseQ
                    parameters.InverseQ = ReadParaItem(ms);
                }
            }
            return parameters;
        }
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string Encrypt(string input)
        {
            byte[] inputBytes = Encoding.UTF8.GetBytes(input);
            using (var rsa = RSA.Create())
            {
                //解码公钥
                RSAParameters parameters = CreateRSAParameters(PubKey);
                rsa.ImportParameters(parameters);
                byte[] result = rsa.Encrypt(inputBytes, RSAEncryptionPadding.Pkcs1);
                return Convert.ToBase64String(result);
            }
        }
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public string Decrypt(string input)
        {
            byte[] inputBytes = Convert.FromBase64String(input);
            using (var rsa = RSA.Create())
            {
                //解码私钥
                RSAParameters parameters = CreateRSAParameters(PrivKey);
                rsa.ImportParameters(parameters);
                byte[] result = rsa.Decrypt(inputBytes, RSAEncryptionPadding.Pkcs1);
                return Encoding.UTF8.GetString(result);
            }
        }
    }
}

Calling code, it is noted here that the encrypted data having a length limit, a maximum of rsa.KeySize / 8, this value may be exceeded by the segment encryption process:

string privateKey = @"MIIEpQIBAAKCAQEA6wA4QhVdyd8vRCsBITcAgJmdcRp6cEaLcLKf3L3F83ufYdxdrEo/d9x+YzIs0O+8FKmf6IABcQJEp20FDeh6oOi+3KIMkvyN1vW+Qmvn1H+BaZ9huBXsE0OdJvyCuJ7iHLX+vGcmskGUKpO71veVsWCzok8Ydoyp/slUpPpN3jTF+MqZSlRT/3Ahh00dDPrOHXz1nhSeP5FUSNMUlK3ziuh/Kff8RewlPJZH+LJjNOl4LrejXo+ktT6lpMTdZsqOIwMd1edPIV6gqlYAxTqfn7I6/eDEbKTu3mNi8mrPxROU3Kadxjgo/it74LUCuNmmjdCtmP8lhI9MPMiwuc2PGQIDAQABAoIBAQC6Br+CGHXZAvLgrIZFa8vbAT9vtD0uObnSKaSA0j0sBDVj+1SvuUrKsGHgVmzBrLUfSjOKkiIR+nCsdJGms9y3GedUsnbvuDrz6i6FV/P59EFWglORrNDnYwO5Q/Sa/zMQ9UTEkYdBXsZSegYdInp+IoWwu5oq5ij/xxJZUsdnWKzPQFk5rnsV0h6YcRWFay32M94lNf30UKiRVuG+WYg3BP6DhUyJRqOotbSCZvxHLaeSqgzvI1x7lhujxjGW1wKNYvsj0Box6VJ9FVrRiizriqOVhc/W27IS68KO1cNAO5YI/SEtPoWElbKL6vXa9/t873wxfhhCE/clV5g58NvtAoGBAPxXicJHEe2hGbyG1Oc9s+piyPzlKY4ginahYVxzO+NWC6rKgCur1u4tnxxpSsuLc51gWJGaEeHulew/sdamjX33afihaGh+bRpSeIH/gwQ5yGbndET+dG4UCC1hBphOE+HquuBmUAgdEZRhRjQkd2cxEQqVX2OSdHuzchzQ9ZznAoGBAO5oU9IfV+koUqHhtETWfiKQaOU9hN4QQnTGZDzVqMPZ8Tx9VTkq09KWz+egJSo7e/M7CsY5M7W0Yix24ku53XRCzYXonGFD4a2NHWSvEAv/C3i/g7A8HuvtMzUU13P3rZn2ozIrO1iUgD8UB5eGbLnsH1E2zcsX8l/xcF4vMfP/AoGBAJopSKn+DT/lmfmJTexvz8izzSJjRj3kN3M+KGL4q2+5k6slx6PmeYpNKNWMpfswGNPeln1taNtkjQcl6pm+ata4Hm+c/FJKWpEoLSMOXJZqTro/UNMNuUe+yTgf/I1ztcXhR4XsO5yZVbIWs3MLjD7oxQZ4Nyx3vt4LxP1B06ulAoGAAVXGOmQAiwa1x8BK0SPeWvUyES6SAuhWZu8BerG7mzUqO6t8AbDytLgxe9uSubTRkeAfxFJnrrnO3u7ff4sP6WnCWuCdl5HYvq8OnhS440hPWSLBawg7KBkQ81gliLm3WChga5SAZZOXUEMdc8TF8RiYaE0FRADjU5Q3i995ySMCgYEAtHt4ZhsKuY8p4WrFDJfeDkbZnIGVMxD1nyIeOLjuhLYUknD2cS0oY7stly77xpCySuTycwbDXRG0njj032v5kl7peOMGxr+ep0h8hrIDjcBa4v4jXTdPofivsPd5Ctb2wX5OTXXN4DRVrGfPnUvjMugQ25EQHu8HTuaX02lmxj0=";

string publicKey = @"MIIBCgKCAQEA6wA4QhVdyd8vRCsBITcAgJmdcRp6cEaLcLKf3L3F83ufYdxdrEo/d9x+YzIs0O+8FKmf6IABcQJEp20FDeh6oOi+3KIMkvyN1vW+Qmvn1H+BaZ9huBXsE0OdJvyCuJ7iHLX+vGcmskGUKpO71veVsWCzok8Ydoyp/slUpPpN3jTF+MqZSlRT/3Ahh00dDPrOHXz1nhSeP5FUSNMUlK3ziuh/Kff8RewlPJZH+LJjNOl4LrejXo+ktT6lpMTdZsqOIwMd1edPIV6gqlYAxTqfn7I6/eDEbKTu3mNi8mrPxROU3Kadxjgo/it74LUCuNmmjdCtmP8lhI9MPMiwuc2PGQIDAQAB";

Encrypt.RSAHelper res = new Encrypt.RSAHelper(privateKey, publicKey);

//加密
string tmpData = res.Encrypt("123456");

//解密
string tmpId = res.Decrypt(tmpData);

 

Published 28 original articles · won praise 2 · views 10000 +

Guess you like

Origin blog.csdn.net/highlevels/article/details/100853052