Linux OpenSSL加解密

使用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

下面加密类使用Pkcs1密钥和公钥,代码如下:

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);
            }
        }
    }
}

调用代码,这里要注意,加密数据有长度限制,最大值为 rsa.KeySize / 8,超过该值可以通过分段加密处理:

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);
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353