生成密钥的方式见: Nodejs 使用RSA加密/解密
- C#.NET使用公钥进行加密
创建两个辅助类
第一个:RSAExtensions
public static class RSAExtensions
{
/// Extension method for initializing a RSACryptoServiceProvider from PEM data string.
#region Methods
/// Extension method which initializes an RSACryptoServiceProvider from a DER public key blob.
public static void LoadPublicKeyDER(this RSACryptoServiceProvider provider, byte[] DERData)
{
byte[] RSAData = GetRSAFromDER(DERData);
byte[] publicKeyBlob = GetPublicKeyBlobFromRSA(RSAData);
provider.importCspBlob(publicKeyBlob);
}
/// Extension method which initializes an RSACryptoServiceProvider from a DER private key blob.
public static void LoadPrivateKeyDER(this RSACryptoServiceProvider provider, byte[] DERData)
{
byte[] privateKeyBlob = GetPrivateKeyDER(DERData);
provider.importCspBlob(privateKeyBlob);
}
/// Extension method which initializes an RSACryptoServiceProvider from a PEM public key string.
public static void LoadPublicKeyPEM(this RSACryptoServiceProvider provider, string sPEM)
{
byte[] DERData = GetDERFromPEM(sPEM);
LoadPublicKeyDER(provider, DERData);
}
/// Extension method which initializes an RSACryptoServiceProvider from a PEM private key string.
public static void LoadPrivateKeyPEM(this RSACryptoServiceProvider provider, string sPEM)
{
byte[] DERData = GetDERFromPEM(sPEM);
LoadPrivateKeyDER(provider, DERData);
}
/// Returns a public key blob from an RSA public key.
internal static byte[] GetPublicKeyBlobFromRSA(byte[] RSAData)
{
byte[] data = null;
UInt32 dwCertPublicKeyBlobSize = 0;
if (CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING,
new IntPtr((int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.NONE,
data, ref dwCertPublicKeyBlobSize))
{
data = new byte[dwCertPublicKeyBlobSize];
if (!CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING,
new IntPtr((int)CRYPT_OUTPUT_TYPES.RSA_CSP_PUBLICKEYBLOB), RSAData, (UInt32)RSAData.Length, CRYPT_DECODE_FLAGS.NONE,
data, ref dwCertPublicKeyBlobSize))
throw new Win32Exception(Marshal.GetLastWin32Error());
}
else
throw new Win32Exception(Marshal.GetLastWin32Error());
return data;
}
/// Converts DER binary format to a CAPI CRYPT_PRIVATE_KEY_INFO structure.
internal static byte[] GetPrivateKeyDER(byte[] DERData)
{
byte[] data = null;
UInt32 dwRSAPrivateKeyBlobSize = 0;
IntPtr pRSAPrivateKeyBlob = IntPtr.Zero;
if (CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.PKCS_RSA_PRIVATE_KEY),
DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwRSAPrivateKeyBlobSize))
{
data = new byte[dwRSAPrivateKeyBlobSize];
if (!CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.PKCS_RSA_PRIVATE_KEY),
DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwRSAPrivateKeyBlobSize))
throw new Win32Exception(Marshal.GetLastWin32Error());
}
else
throw new Win32Exception(Marshal.GetLastWin32Error());
return data;
}
/// Converts DER binary format to a CAPI CERT_PUBLIC_KEY_INFO structure containing an RSA key.
internal static byte[] GetRSAFromDER(byte[] DERData)
{
byte[] data = null;
byte[] publicKey = null;
CERT_PUBLIC_KEY_INFO info;
UInt32 dwCertPublicKeyInfoSize = 0;
IntPtr pCertPublicKeyInfo = IntPtr.Zero;
if (CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO),
DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwCertPublicKeyInfoSize))
{
data = new byte[dwCertPublicKeyInfoSize];
if (CryptDecodeObject(CRYPT_ENCODING_FLAGS.X509_ASN_ENCODING | CRYPT_ENCODING_FLAGS.PKCS_7_ASN_ENCODING, new IntPtr((int)CRYPT_OUTPUT_TYPES.X509_PUBLIC_KEY_INFO),
DERData, (UInt32)DERData.Length, CRYPT_DECODE_FLAGS.NONE, data, ref dwCertPublicKeyInfoSize))
{
GCHandle handle = GCHandle.Alloc(data, GCHandleType.Pinned);
try
{
info = (CERT_PUBLIC_KEY_INFO)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(CERT_PUBLIC_KEY_INFO));
publicKey = new byte[info.PublicKey.cbData];
Marshal.Copy(info.PublicKey.pbData, publicKey, 0, publicKey.Length);
}
finally
{
handle.Free();
}
}
else
throw new Win32Exception(Marshal.GetLastWin32Error());
}
else
throw new Win32Exception(Marshal.GetLastWin32Error());
return publicKey;
}
/// Extracts the binary data from a PEM file.
internal static byte[] GetDERFromPEM(string sPEM)
{
UInt32 dwSkip, dwFlags;
UInt32 dwBinarySize = 0;
if (!CryptStringToBinary(sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_base64HEADER, null, ref dwBinarySize, out dwSkip, out dwFlags))
throw new Win32Exception(Marshal.GetLastWin32Error());
byte[] decodedData = new byte[dwBinarySize];
if (!CryptStringToBinary(sPEM, (UInt32)sPEM.Length, CRYPT_STRING_FLAGS.CRYPT_STRING_base64HEADER, decodedData, ref dwBinarySize, out dwSkip, out dwFlags))
throw new Win32Exception(Marshal.GetLastWin32Error());
return decodedData;
}
#endregion Methods
#region P/Invoke Constants
/// Enumeration derived from Crypto API.
internal enum CRYPT_ACQUIRE_CONTEXT_FLAGS : uint
{
CRYPT_NEWKEYSET = 0x8,
CRYPT_DELETeKEYSET = 0x10,
CRYPT_MACHINE_KEYSET = 0x20,
CRYPT_SILENT = 0x40,
CRYPT_DEFAULT_CONTAINER_OPTIonAL = 0x80,
CRYPT_VERIFYConTEXT = 0xF0000000
}
/// Enumeration derived from Crypto API.
internal enum CRYPT_PROVIDER_TYPE : uint
{
PROV_RSA_FULL = 1
}
/// Enumeration derived from Crypto API.
internal enum CRYPT_DECODE_FLAGS : uint
{
NONE = 0,
CRYPT_DECODE_ALLOC_FLAG = 0x8000
}
/// Enumeration derived from Crypto API.
internal enum CRYPT_ENCODING_FLAGS : uint
{
PKCS_7_ASN_ENCODING = 0x00010000,
X509_ASN_ENCODING = 0x00000001,
}
/// Enumeration derived from Crypto API.
internal enum CRYPT_OUTPUT_TYPES : int
{
X509_PUBLIC_KEY_INFO = 8,
RSA_CSP_PUBLICKEYBLOB = 19,
PKCS_RSA_PRIVATE_KEY = 43,
PKCS_PRIVATE_KEY_INFO = 44
}
/// Enumeration derived from Crypto API.
internal enum CRYPT_STRING_FLAGS : uint
{
CRYPT_STRING_base64HEADER = 0,
CRYPT_STRING_base64 = 1,
CRYPT_STRING_BINARY = 2,
CRYPT_STRING_base64REQUESTHEADER = 3,
CRYPT_STRING_HEX = 4,
CRYPT_STRING_HEXASCII = 5,
CRYPT_STRING_base64_ANY = 6,
CRYPT_STRING_ANY = 7,
CRYPT_STRING_HEX_ANY = 8,
CRYPT_STRING_base64X509CRLHEADER = 9,
CRYPT_STRING_HEXADDR = 10,
CRYPT_STRING_HEXASCIIADDR = 11,
CRYPT_STRING_HEXRAW = 12,
CRYPT_STRING_NOCRLF = 0x40000000,
CRYPT_STRING_NOCR = 0x80000000
}
#endregion P/Invoke Constants
#region P/Invoke Structures
/// Structure from Crypto API.
[StructLayout(LayoutKind.Sequential)]
internal struct CRYPT_OBJID_BLOB
{
internal UInt32 cbData;
internal IntPtr pbData;
}
/// Structure from Crypto API.
[StructLayout(LayoutKind.Sequential)]
internal struct CRYPT_ALGORITHM_IDENTIFIER
{
internal IntPtr pszObjId;
internal CRYPT_OBJID_BLOB Parameters;
}
/// Structure from Crypto API.
[StructLayout(LayoutKind.Sequential)]
struct CRYPT_BIT_BLOB
{
internal UInt32 cbData;
internal IntPtr pbData;
internal UInt32 cUnusedBits;
}
/// Structure from Crypto API.
[StructLayout(LayoutKind.Sequential)]
struct CERT_PUBLIC_KEY_INFO
{
internal CRYPT_ALGORITHM_IDENTIFIER Algorithm;
internal CRYPT_BIT_BLOB PublicKey;
}
#endregion P/Invoke Structures
#region P/Invoke Functions
/// Function for Crypto API.
[Dllimport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CryptDestroyKey(IntPtr hKey);
/// Function for Crypto API.
[Dllimport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CryptimportKey(IntPtr hProv, byte[] pbKeyData, UInt32 dwDataLen, IntPtr hPubKey, UInt32 dwFlags, ref IntPtr hKey);
/// Function for Crypto API.
[Dllimport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CryptReleaseContext(IntPtr hProv, Int32 dwFlags);
/// Function for Crypto API.
[Dllimport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CryptAcquireContext(ref IntPtr hProv, string pszContainer, string pszProvider, CRYPT_PROVIDER_TYPE dwProvType, CRYPT_ACQUIRE_CONTEXT_FLAGS dwFlags);
/// Function from Crypto API.
[Dllimport("crypt32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CryptStringToBinary(string sPEM, UInt32 sPEMLength, CRYPT_STRING_FLAGS dwFlags, [Out] byte[] pbBinary, ref UInt32 pcbBinary, out UInt32 pdwSkip, out UInt32 pdwFlags);
/// Function from Crypto API.
[Dllimport("crypt32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CryptDecodeObjectEx(CRYPT_ENCODING_FLAGS dwCertEncodingType, IntPtr lpszStructType, byte[] pbEncoded, UInt32 cbEncoded, CRYPT_DECODE_FLAGS dwFlags, IntPtr pDecodePara, ref byte[] pvStructInfo, ref UInt32 pcbStructInfo);
/// Function from Crypto API.
[Dllimport("crypt32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CryptDecodeObject(CRYPT_ENCODING_FLAGS dwCertEncodingType, IntPtr lpszStructType, byte[] pbEncoded, UInt32 cbEncoded, CRYPT_DECODE_FLAGS flags, [In, Out] byte[] pvStructInfo, ref UInt32 cbStructInfo);
#endregion P/Invoke Functions
}
第二个:RSAHelper
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
public abstract class RSAHelper
{
#region 加密
// ///
// /// RSA加密PEM秘钥(普通PKCS#1格式)
// ///
// ///
// ///
// ///
// ///
// public static string EncryptPEM(string publicKeyPEM, string data, string encoding = "UTF-8")
// {
//#if false
// RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
// byte[] cipherbytes;
// rsa.LoadPublicKeyPEM(publicKeyPEM);
// //☆☆☆☆.NET 4.6以后特有☆☆☆☆
// //HashAlgorithmName hashName = new System.Security.Cryptography.HashAlgorithmName(hashAlgorithm);
// //RSAEncryptionPadding padding = RSAEncryptionPadding.OaepSHA512;//RSAEncryptionPadding.CreateOaep(hashName);//.NET 4.6以后特有
// //cipherbytes = rsa.Encrypt(Encoding.GetEncoding(encoding).GetBytes(data), padding);
// //☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
// //☆☆☆☆.NET 4.6以前请用此段代码☆☆☆☆
// cipherbytes = rsa.Encrypt(Encoding.GetEncoding(encoding).GetBytes(data), false);
// return Convert.Tobase64String(cipherbytes);
//#else
// if (string.IsNullOrEmpty(data))
// {
// return string.Empty;
// }
// if (string.IsNullOrWhiteSpace(publicKeyPEM))
// {
// throw new ArgumentException("Invalid Public Key");
// }
// using (var rsa = new RSACryptoServiceProvider())
// {
// var inputBytes = Encoding.GetEncoding(encoding).GetBytes(data);//有含义的字符串转化为字节流
// rsa.LoadPublicKeyPEM(publicKeyPEM);//载入公钥
// int bufferSize = (rsa.KeySize / 8) - 11;//单块最大长度
// var buffer = new byte[bufferSize];
// using (MemoryStream inputStream = new MemoryStream(inputBytes),
//outputStream = new MemoryStream())
// {
// while (true)
// { //分段加密
// int readSize = inputStream.Read(buffer, 0, bufferSize);
// if (readSize <= 0)
// {
//break;
// }
// var temp = new byte[readSize];
// Array.Copy(buffer, 0, temp, 0, readSize);
// var encryptedBytes = rsa.Encrypt(temp, false);
// outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);
// }
// return Convert.Tobase64String(outputStream.ToArray());//转化为字节流方便传输
// }
// }
//#endif
// }
///
/// RSA加密PEM秘钥(普通PKCS#1格式)
///
///
///
///
///
public static string EncryptPEM(string publicKeyPEM, string data, string encoding = "UTF-8")
{
#if false
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.LoadPublicKeyPEM(publicKeyPEM);
//☆☆☆☆.NET 4.6以后特有☆☆☆☆
//HashAlgorithmName hashName = new System.Security.Cryptography.HashAlgorithmName(hashAlgorithm);
//RSAEncryptionPadding padding = RSAEncryptionPadding.OaepSHA512;//RSAEncryptionPadding.CreateOaep(hashName);//.NET 4.6以后特有
//cipherbytes = rsa.Encrypt(Encoding.GetEncoding(encoding).GetBytes(data), padding);
//☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
//☆☆☆☆.NET 4.6以前请用此段代码☆☆☆☆
cipherbytes = rsa.Encrypt(Encoding.GetEncoding(encoding).GetBytes(data), false);
return Convert.Tobase64String(cipherbytes);
#else
if (string.IsNullOrEmpty(data))
{
return string.Empty;
}
if (string.IsNullOrWhiteSpace(publicKeyPEM))
{
throw new ArgumentException("Invalid Public Key");
}
using (var rsa = new RSACryptoServiceProvider())
{
rsa.LoadPublicKeyPEM(publicKeyPEM);//载入公钥
byte[] plainText = Encoding.GetEncoding(encoding).GetBytes(data);
byte[] cypherText = rsa.Encrypt(plainText, false);
return Convert.Tobase64String(cypherText);
}
#endif
}
///
/// RSA加密
///
///
///
///
///
public static string EncryptCSharp(string publicKeyCSharp, string data, string encoding = "UTF-8")
{
#if false
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(publicKeyCSharp);
//☆☆☆☆.NET 4.6以后特有☆☆☆☆
//HashAlgorithmName hashName = new System.Security.Cryptography.HashAlgorithmName(hashAlgorithm);
//RSAEncryptionPadding padding = RSAEncryptionPadding.OaepSHA512;//RSAEncryptionPadding.CreateOaep(hashName);//.NET 4.6以后特有
//cipherbytes = rsa.Encrypt(Encoding.GetEncoding(encoding).GetBytes(data), padding);
//☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
//☆☆☆☆.NET 4.6以前请用此段代码☆☆☆☆
cipherbytes = rsa.Encrypt(Encoding.GetEncoding(encoding).GetBytes(data), false);
return Convert.Tobase64String(cipherbytes);
#else
if (string.IsNullOrEmpty(data))
{
return string.Empty;
}
if (string.IsNullOrWhiteSpace(publicKeyCSharp))
{
throw new ArgumentException("Invalid Public Key");
}
using (var rsa = new RSACryptoServiceProvider())
{
var inputBytes = Encoding.GetEncoding(encoding).GetBytes(data);//有含义的字符串转化为字节流
rsa.FromXmlString(publicKeyCSharp);//载入公钥
int bufferSize = (rsa.KeySize / 8) - 11;//单块最大长度
var buffer = new byte[bufferSize];
using (MemoryStream inputStream = new MemoryStream(inputBytes),
outputStream = new MemoryStream())
{
while (true)
{ //分段加密
int readSize = inputStream.Read(buffer, 0, bufferSize);
if (readSize <= 0)
{
break;
}
var temp = new byte[readSize];
Array.Copy(buffer, 0, temp, 0, readSize);
var encryptedBytes = rsa.Encrypt(temp, false);
outputStream.Write(encryptedBytes, 0, encryptedBytes.Length);
}
return Convert.Tobase64String(outputStream.ToArray());//转化为字节流方便传输
}
}
#endif
}
#endregion
#region 解密
// ///
// /// RSA解密(普通PKCS#1格式)
// ///
// ///
// ///
// ///
// ///
// public static string DecryptPEM(string privateKeyPEM, string data, string encoding = "UTF-8")
// {
//#if false
// RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
// byte[] cipherbytes;
// rsa.LoadPrivateKeyPEM(privateKeyPEM);
// //☆☆☆☆.NET 4.6以后特有☆☆☆☆
// //RSAEncryptionPadding padding = RSAEncryptionPadding.CreateOaep(new System.Security.Cryptography.HashAlgorithmName(hashAlgorithm));//.NET 4.6以后特有
// //cipherbytes = rsa.Decrypt(Encoding.GetEncoding(encoding).GetBytes(data), padding);
// //☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
// //☆☆☆☆.NET 4.6以前请用此段代码☆☆☆☆
// cipherbytes = rsa.Decrypt(Convert.Frombase64String(data), false);
// return Encoding.GetEncoding(encoding).GetString(cipherbytes);
//#else
// if (string.IsNullOrEmpty(data))
// {
// return string.Empty;
// }
// if (string.IsNullOrWhiteSpace(privateKeyPEM))
// {
// throw new ArgumentException("Invalid Private Key");
// }
// using (var rsa = new RSACryptoServiceProvider())
// {
// var inputBytes = Convert.Frombase64String(data);
// rsa.LoadPrivateKeyPEM(privateKeyPEM);
// int bufferSize = rsa.KeySize / 8;
// var buffer = new byte[bufferSize];
// using (MemoryStream inputStream = new MemoryStream(inputBytes),
//outputStream = new MemoryStream())
// {
// while (true)
// {
// int readSize = inputStream.Read(buffer, 0, bufferSize);
// if (readSize <= 0)
// {
//break;
// }
// var temp = new byte[readSize];
// Array.Copy(buffer, 0, temp, 0, readSize);
// var rawBytes = rsa.Decrypt(temp, false);
// outputStream.Write(rawBytes, 0, rawBytes.Length);
// }
// return Encoding.GetEncoding(encoding).GetString(outputStream.ToArray());
// }
// }
//#endif
// }
///
/// RSA解密(普通PKCS#1格式)
///
///
///
///
///
public static string DecryptPEM(string privateKeyPEM, string data, string encoding = "UTF-8")
{
#if false
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.LoadPrivateKeyPEM(privateKeyPEM);
//☆☆☆☆.NET 4.6以后特有☆☆☆☆
//RSAEncryptionPadding padding = RSAEncryptionPadding.CreateOaep(new System.Security.Cryptography.HashAlgorithmName(hashAlgorithm));//.NET 4.6以后特有
//cipherbytes = rsa.Decrypt(Encoding.GetEncoding(encoding).GetBytes(data), padding);
//☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
//☆☆☆☆.NET 4.6以前请用此段代码☆☆☆☆
cipherbytes = rsa.Decrypt(Convert.Frombase64String(data), false);
return Encoding.GetEncoding(encoding).GetString(cipherbytes);
#else
if (string.IsNullOrEmpty(data))
{
return string.Empty;
}
if (string.IsNullOrWhiteSpace(privateKeyPEM))
{
throw new ArgumentException("Invalid Private Key");
}
using (var rsa = new RSACryptoServiceProvider())
{
rsa.LoadPrivateKeyPEM(privateKeyPEM);
byte[] plainText = Convert.Frombase64String(data);
byte[] dypherText = rsa.Decrypt(plainText, false);
return Encoding.GetEncoding(encoding).GetString(dypherText);
}
#endif
}
///
/// RSA解密
///
///
///
///
///
public static string DecryptCSharp(string privateKeyCSharp, string data, string encoding = "UTF-8")
{
#if false
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
byte[] cipherbytes;
rsa.FromXmlString(privateKeyCSharp);
//☆☆☆☆.NET 4.6以后特有☆☆☆☆
//RSAEncryptionPadding padding = RSAEncryptionPadding.CreateOaep(new System.Security.Cryptography.HashAlgorithmName(hashAlgorithm));//.NET 4.6以后特有
//cipherbytes = rsa.Decrypt(Encoding.GetEncoding(encoding).GetBytes(data), padding);
//☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
//☆☆☆☆.NET 4.6以前请用此段代码☆☆☆☆
cipherbytes = rsa.Decrypt(Convert.Frombase64String(data), false);
return Encoding.GetEncoding(encoding).GetString(cipherbytes);
#else
if (string.IsNullOrEmpty(data))
{
return string.Empty;
}
if (string.IsNullOrWhiteSpace(privateKeyCSharp))
{
throw new ArgumentException("Invalid Private Key");
}
using (var rsa = new RSACryptoServiceProvider())
{
var inputBytes = Convert.Frombase64String(data);
rsa.FromXmlString(privateKeyCSharp);
int bufferSize = rsa.KeySize / 8;
var buffer = new byte[bufferSize];
using (MemoryStream inputStream = new MemoryStream(inputBytes),
outputStream = new MemoryStream())
{
while (true)
{
int readSize = inputStream.Read(buffer, 0, bufferSize);
if (readSize <= 0)
{
break;
}
var temp = new byte[readSize];
Array.Copy(buffer, 0, temp, 0, readSize);
var rawBytes = rsa.Decrypt(temp, false);
outputStream.Write(rawBytes, 0, rawBytes.Length);
}
return Encoding.GetEncoding(encoding).GetString(outputStream.ToArray());
}
}
#endif
}
#endregion
#region 加签
///
/// RSA签名
///
/// 私钥
/// 待签名的内容
///
public static string RSASignPEM(string data, string privateKeyPEM, string hashAlgorithm = "MD5", string encoding = "UTF-8")
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.LoadPrivateKeyPEM(privateKeyPEM);//加载私钥
var dataBytes = Encoding.GetEncoding(encoding).GetBytes(data);
var HashbyteSignature = rsa.SignData(dataBytes, hashAlgorithm);
return Convert.Tobase64String(HashbyteSignature);
}
///
/// RSA签名CSharp
///
/// 私钥
/// 待签名的内容
///
public static string RSASignCSharp(string data, string privateKeyCSharp, string hashAlgorithm = "MD5", string encoding = "UTF-8")
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
rsa.FromXmlString(privateKeyCSharp);//加载私钥
var dataBytes = Encoding.GetEncoding(encoding).GetBytes(data);
var HashbyteSignature = rsa.SignData(dataBytes, hashAlgorithm);
return Convert.Tobase64String(HashbyteSignature);
}
#endregion
#region 验签
///
/// 验证签名PEM
///
///
///
///
///
public static bool VerifyPEM(string data, string publicKeyPEM, string signature, string hashAlgorithm = "MD5", string encoding = "UTF-8")
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
//导入公钥,准备验证签名
rsa.LoadPublicKeyPEM(publicKeyPEM);
//返回数据验证结果
byte[] Data = Encoding.GetEncoding(encoding).GetBytes(data);
byte[] rgbSignature = Convert.Frombase64String(signature);
return rsa.VerifyData(Data, hashAlgorithm, rgbSignature);
}
///
/// 验证签名CSharp
///
///
///
///
///
public static bool VerifyCSharp(string data, string publicKeyCSharp, string signature, string hashAlgorithm = "MD5", string encoding = "UTF-8")
{
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider();
//导入公钥,准备验证签名
rsa.LoadPublicKeyPEM(publicKeyCSharp);
//返回数据验证结果
byte[] Data = Encoding.GetEncoding(encoding).GetBytes(data);
byte[] rgbSignature = Convert.Frombase64String(signature);
return rsa.VerifyData(Data, hashAlgorithm, rgbSignature);
}
#endregion
}
加密:
static string publicPath = ConfigurationManager.AppSettings["publicPath"].ToString();
static string privatePath = ConfigurationManager.AppSettings["privatePath"].ToString();
static string getPublicKey()
{
string publicKey = "";
using (StreamReader sr = new StreamReader(publicPath))
{
publicKey = sr.ReadToEnd();
}
return publicKey;
}
static string getPrivateKey()
{
string privateKey = "";
using (StreamReader sr = new StreamReader(privatePath))
{
privateKey = sr.ReadToEnd();
}
return privateKey;
}
static void Main(string[] args)
{
string publicKey = getPublicKey();
string privateKey = getPrivateKey();
string data = "JodieTestPem";
string encryptResult = RSAHelper.EncryptPEM(publicKey, data);
Console.WriteLine("encryptResult:" + encryptResult);
//string decryptResult = RSAHelper.DecryptPEM(privateKey, encryptResult);
//Console.WriteLine("decryptResult:" + decryptResult);
Console.ReadKey();
}
- Nodejs使用私钥进行解密
const NodeRSA=require('node-rsa')
const fs=require('fs')
const publicKeyPath='./pem/public.pem'
const privateKeyPath='./pem/private.pem'
//.NET加密结果
var encrypted="v+WhKpT/o8lP40c8Bst6V27mXb3dwvTjE9f/ssuBTL3wEefjsvRwnski0ruO/ye/vXNjbED3aEmkjx/S5m6eBA=="
fs.exists(privateKeyPath,function (exists) {
if(exists){
var pem=fs.readFileSync(privateKeyPath,'utf8')
var key=new NodeRSA(pem,{'encryptionScheme': 'pkcs1'})
var decrypted=key.decrypt(encrypted,'utf8')
console.log('decrypted:'+decrypted)
}
})



