使用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
{
///
/// RSA加密算法(验签部分还没加入)
///
public class RSAHelper
{
private RSA rsa;
///
/// 公钥
///
public string PubKey { get; private set; }
///
/// 私钥
///
public string PrivKey { get; private set; }
public RSAHelper(string privKey, string pubKey)
{
this.PrivKey = privKey;
this.PubKey = pubKey;
}
///
/// 读取密钥参数
///
///
///
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 resultBytes = new List();
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;
}
}
///
/// 解析Pkcs1密钥
///
///
///
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;
}
///
/// 加密
///
///
///
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);
}
}
///
/// 解密
///
///
///
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);