384 lines
15 KiB
C#
384 lines
15 KiB
C#
using System.Security.Cryptography;
|
||
using System.Text;
|
||
|
||
namespace Szmedi.AIScriptRunner.Web
|
||
{
|
||
public class RSAHelper
|
||
{
|
||
//private static String pubJavaKey = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCHoDne3LBben7VT0dvBmmpbO2iNet/PBkTvkWE" +
|
||
// "/WfYO8Yx+oNcLXBkyxLBlV+HRAjOG1LNmzhpHQySLNc+KK/iXaAPyHSZAEGsA/eh731FCKLcSlEA" +
|
||
// "M0rXS2HpeJFvLEfj5q9Yabzp/TkQBUt3epxZ/0BIXFCxa8Grr0w6oBs0NwIDAQAB";
|
||
|
||
//private static string PublicKey =
|
||
|
||
//"<RSAKeyValue><Modulus>6CdsXgYOyya/yQH" +
|
||
//"TO96dB3gEurM2UQDDVGrZoe6RcAVTxAqDDf5L" +
|
||
//"wPycZwtNOx3Cfy44/D5Mj86koPew5soFIz9sx" +
|
||
//"PAHRF5hcqJoG+q+UfUYTHYCsMH2cnqGVtnQiE" +
|
||
//"/PMRMmY0RwEfMIo+TDpq3QyO03MaEsDGf13sP" +
|
||
//"w9YRXiac=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
|
||
|
||
private static string privateKey =
|
||
"<RSAKeyValue><Modulus>6CdsXgYOyya/yQH" +
|
||
"TO96dB3gEurM2UQDDVGrZoe6RcAVTxAqDDf5L" +
|
||
"wPycZwtNOx3Cfy44/D5Mj86koPew5soFIz9sx" +
|
||
"PAHRF5hcqJoG+q+UfUYTHYCsMH2cnqGVtnQiE" +
|
||
"/PMRMmY0RwEfMIo+TDpq3QyO03MaEsDGf13sP" +
|
||
"w9YRXiac=</Modulus><Exponent>AQAB</Exponent>" +
|
||
"<P>/aoce2r6tonjzt1IQI6FM4ysR40j/gKvt4d" +
|
||
|
||
"L411pUop1Zg61KvCm990M4uN6K8R/DUvAQdrRd" +
|
||
|
||
"VgzvvAxXD7ESw==</P><Q>6kqclrEunX/fmOle" +
|
||
|
||
"VTxG4oEpXY4IJumXkLpylNR3vhlXf6ZF9obEpG" +
|
||
|
||
"lq0N7sX2HBxa7T2a0WznOAb0si8FuelQ==</Q>" +
|
||
|
||
"<DP>3XEvxB40GD5v/Rr4BENmzQW1MBFqpki6FU" +
|
||
|
||
"GrYiUd2My+iAW26nGDkUYMBdYHxUWYlIbYo6Te" +
|
||
|
||
"zc3d/oW40YqJ2Q==</DP><DQ>LK0XmQCmY/ArY" +
|
||
|
||
"gw2Kci5t51rluRrl4f5l+aFzO2K+9v3PGcndjA" +
|
||
|
||
"StUtIzBWGO1X3zktdKGgCLlIGDrLkMbM21Q==</DQ><InverseQ>" +
|
||
|
||
"GqC4Wwsk2fdvJ9dmgYlej8mTDBWg0Wm6aqb5kjn" +
|
||
|
||
"cWK6WUa6CfD+XxfewIIq26+4Etm2A8IAtRdwPl4" +
|
||
|
||
"aPjSfWdA==</InverseQ><D>a1qfsDMY8DSxB2D" +
|
||
|
||
"Cr7LX5rZHaZaqDXdO3GC01z8dHjI4dDVwOS5ZFZ" +
|
||
|
||
"s7MCN3yViPsoRLccnVWcLzOkSQF4lgKfTq3IH40" +
|
||
|
||
"H5N4gg41as9GbD0g9FC3n5IT4VlVxn9ZdW+WQry" +
|
||
|
||
"oHdbiIAiNpFKxL/DIEERur4sE1Jt9VdZsH24CJE=</D></RSAKeyValue>";
|
||
|
||
public static string Decrypt(string base64code)
|
||
{
|
||
|
||
try
|
||
{
|
||
|
||
//Create a UnicodeEncoder to convert between byte array and string.
|
||
UnicodeEncoding ByteConverter = new UnicodeEncoding();
|
||
|
||
//Create a new instance of RSACryptoServiceProvider to generate
|
||
//public and private key data.
|
||
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
|
||
RSA.FromXmlString(privateKey);
|
||
byte[] encryptedData;
|
||
byte[] decryptedData;
|
||
encryptedData = Convert.FromBase64String(base64code);
|
||
|
||
//Pass the data to DECRYPT, the private key information
|
||
//(using RSACryptoServiceProvider.ExportParameters(true),
|
||
//and a boolean flag specifying no OAEP padding.
|
||
decryptedData = RSADecrypt(encryptedData, RSA.ExportParameters(true), false);
|
||
//Display the decrypted plaintext to the console.
|
||
return ByteConverter.GetString(decryptedData);
|
||
|
||
}
|
||
|
||
catch (Exception exc)
|
||
{
|
||
//Exceptions.LogException(exc);
|
||
Console.WriteLine(exc.Message);
|
||
return string.Empty;
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加密
|
||
/// </summary>
|
||
/// <param name="toEncryptString"></param>
|
||
/// <returns></returns>
|
||
static public string Encrypt(string toEncryptString)
|
||
{
|
||
|
||
try
|
||
{
|
||
|
||
//string key = "";
|
||
|
||
//Create a UnicodeEncoder to convert between byte array and string.
|
||
UnicodeEncoding ByteConverter = new UnicodeEncoding();
|
||
//Create byte arrays to hold original, encrypted, and decrypted data.
|
||
|
||
byte[] dataToEncrypt = ByteConverter.GetBytes(toEncryptString);
|
||
byte[] encryptedData;
|
||
//byte[] decryptedData;
|
||
//Create a new instance of RSACryptoServiceProvider to generate
|
||
//public and private key data.
|
||
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
|
||
RSA.FromXmlString(privateKey);
|
||
|
||
|
||
|
||
//Pass the data to ENCRYPT, the public key information
|
||
//(using RSACryptoServiceProvider.ExportParameters(false),
|
||
//and a boolean flag specifying no OAEP padding.
|
||
encryptedData = RSAEncrypt(dataToEncrypt, RSA.ExportParameters(false), false);
|
||
string base64code = Convert.ToBase64String(encryptedData);
|
||
return base64code;
|
||
}
|
||
|
||
catch (Exception exc)
|
||
{
|
||
|
||
//Catch this exception in case the encryption did
|
||
//not succeed.
|
||
//Exceptions.LogException(exc);
|
||
Console.WriteLine(exc.Message);
|
||
return string.Empty;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 解密
|
||
/// </summary>
|
||
/// <param name="DataToEncrypt"></param>
|
||
/// <param name="RSAKeyInfo"></param>
|
||
/// <param name="DoOAEPPadding"></param>
|
||
/// <returns></returns>
|
||
static private byte[] RSAEncrypt(byte[] DataToEncrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
|
||
{
|
||
try
|
||
{
|
||
|
||
//Create a new instance of RSACryptoServiceProvider.
|
||
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
|
||
|
||
//Import the RSA Key information. This only needs
|
||
//toinclude the public key information.
|
||
RSA.ImportParameters(RSAKeyInfo);
|
||
//Encrypt the passed byte array and specify OAEP padding.
|
||
//OAEP padding is only available on Microsoft Windows XP or
|
||
//later.
|
||
return RSA.Encrypt(DataToEncrypt, DoOAEPPadding);
|
||
}
|
||
|
||
//Catch and display a CryptographicException
|
||
//to the console.
|
||
catch (CryptographicException e)
|
||
{
|
||
//Exceptions.LogException(e);
|
||
Console.WriteLine(e.Message);
|
||
return null;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
static private byte[] RSADecrypt(byte[] DataToDecrypt, RSAParameters RSAKeyInfo, bool DoOAEPPadding)
|
||
{
|
||
|
||
try
|
||
{
|
||
//Create a new instance of RSACryptoServiceProvider.
|
||
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
|
||
|
||
//Import the RSA Key information. This needs
|
||
//to include the private key information.
|
||
RSA.ImportParameters(RSAKeyInfo);
|
||
|
||
//Decrypt the passed byte array and specify OAEP padding.
|
||
//OAEP padding is only available on Microsoft Windows XP or
|
||
//later.
|
||
return RSA.Decrypt(DataToDecrypt, DoOAEPPadding);
|
||
}
|
||
|
||
//Catch and display a CryptographicException
|
||
//to the console.
|
||
catch (CryptographicException e)
|
||
{
|
||
//Exceptions.LogException(e);
|
||
Console.WriteLine(e.Message);
|
||
return null;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 加密
|
||
/// </summary>
|
||
/// <param name="data"></param>
|
||
/// <returns></returns>
|
||
public static string EncryptByJavaKey(string pubKey, string data)
|
||
{
|
||
//const int PROVIDER_RSA_FULL = 1;
|
||
//const string CONTAINER_NAME = "Tracker";
|
||
|
||
//CspParameters cspParams;
|
||
//cspParams = new CspParameters(PROVIDER_RSA_FULL);
|
||
//cspParams.KeyContainerName = CONTAINER_NAME;
|
||
//RSACryptoServiceProvider rsa1 = new RSACryptoServiceProvider(cspParams);
|
||
//rsa1.FromXmlString("<RSAKeyValue><Modulus>2rRVVVFJRbH/wAPDtnwZwu+nxU+AZ6uXxh/sW+AMCBogg7vndZsnRiHoLttYYPqOyOhfgaBOQogrIfrKL4lipK4m52SBzw/FfcM9DsKs/rYR83tBLiIAfgdnVjF27tZID+HJMFTiI30mALjr7+tfp+2lIACXA1RIKTk7S9pDmX8=</Modulus><Exponent>AQAB</Exponent><P>92jJJyzFBSx6gL4Y1YpALmc5CNjoE/wETjqb3ci2v0+3rZWvJKmKy1ZEdlXpyuvXVksJ6cMdUpNAkMknUk9pTQ==</P><Q>4kxkABZOXyDLryYGCGY0b8N0FIdu5BTCFDYEdcatxl/f7ZGDS1NgHJpUWxkVXFfHy2Y/GuDOIbpcwlsO739H+w==</Q><DP>5bNFvrdUHF+VRN45VFjNCcgQLeSkY5mBrdfASoNFGA29LM5iE5nNIMfxPCS7sQiRnq6Af6YFHVtVgJchiMvtqQ==</DP><DQ>j+ng1qVY5epnXlWiFIla45C7K6sNfIMvAcdwgq39KWEjeWPGyYqWXtpOtzh2eylf6Bx4GVHKBW0NPJTIJMsfLQ==</DQ><InverseQ>8uu0dfPVDqB2qFM1Vdi8hl+2uZtN7gjT2co1cEWy29HVYBZD0k9KKCf2PbkeuSfpgFpE70wW5Hrp8V7l/SwSOw==</InverseQ><D>MM/c18zroJ2Iqi9s5/asvUBF3pjO3NSEbFjFpP/NT6WdKimvECWPz2xT6NlV0Vc6tQaAAmtn7Bt+HPhfVdrA4/ysYVe3/6TWkPjW+bvAhMWu/ZqISx11/jPYSGD9g3ZXgUiqcQM8UbOjlswoq4fpheEXTB0xdVutDLpO3qgHN6k=</D></RSAKeyValue>");
|
||
|
||
//获取公钥:服务器返回一个字符串(pubKey),这是一个 Base64 格式的公钥数据。
|
||
//解析公钥:将 Base64 还原为字节数组,并解析成 RSA 公钥对象(对应 C# 的 DecodeX509PublicKey)。
|
||
//准备数据:将密码字符串转为字节数组(UTF - 8)。
|
||
//RSA 加密:使用解析出来的公钥对密码字节进行加密。
|
||
//再次 Base64:将加密后的乱码字节数组,转回 Base64 字符串,以便通过 HTTP 发送给服务器。
|
||
byte[] bytes = Convert.FromBase64String(pubKey);
|
||
RSACryptoServiceProvider rsa1 = DecodeX509PublicKey(bytes);
|
||
|
||
System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
|
||
byte[] textBytes = encoding.GetBytes(data);
|
||
byte[] encryptedOutput = rsa1.Encrypt(textBytes, false);
|
||
string outputB64 = Convert.ToBase64String(encryptedOutput);
|
||
//Debug.WriteLine(outputB64);
|
||
return outputB64;
|
||
}
|
||
|
||
public static RSACryptoServiceProvider DecodeX509PublicKey(byte[] x509key)
|
||
{
|
||
byte[] SeqOID = { 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 };
|
||
|
||
MemoryStream ms = new MemoryStream(x509key);
|
||
BinaryReader reader = new BinaryReader(ms);
|
||
|
||
if (reader.ReadByte() == 0x30)
|
||
ReadASNLength(reader); //skip the size
|
||
else
|
||
return null;
|
||
|
||
int identifierSize = 0; //total length of Object Identifier section
|
||
if (reader.ReadByte() == 0x30)
|
||
identifierSize = ReadASNLength(reader);
|
||
else
|
||
return null;
|
||
|
||
if (reader.ReadByte() == 0x06) //is the next element an object identifier?
|
||
{
|
||
int oidLength = ReadASNLength(reader);
|
||
byte[] oidBytes = new byte[oidLength];
|
||
reader.Read(oidBytes, 0, oidBytes.Length);
|
||
if (oidBytes.SequenceEqual(SeqOID) == false) //is the object identifier rsaEncryption PKCS#1?
|
||
return null;
|
||
|
||
int remainingBytes = identifierSize - 2 - oidBytes.Length;
|
||
reader.ReadBytes(remainingBytes);
|
||
}
|
||
|
||
if (reader.ReadByte() == 0x03) //is the next element a bit string?
|
||
{
|
||
ReadASNLength(reader); //skip the size
|
||
reader.ReadByte(); //skip unused bits indicator
|
||
if (reader.ReadByte() == 0x30)
|
||
{
|
||
ReadASNLength(reader); //skip the size
|
||
if (reader.ReadByte() == 0x02) //is it an integer?
|
||
{
|
||
int modulusSize = ReadASNLength(reader);
|
||
byte[] modulus = new byte[modulusSize];
|
||
reader.Read(modulus, 0, modulus.Length);
|
||
if (modulus[0] == 0x00) //strip off the first byte if it's 0
|
||
{
|
||
byte[] tempModulus = new byte[modulus.Length - 1];
|
||
Array.Copy(modulus, 1, tempModulus, 0, modulus.Length - 1);
|
||
modulus = tempModulus;
|
||
}
|
||
|
||
if (reader.ReadByte() == 0x02) //is it an integer?
|
||
{
|
||
int exponentSize = ReadASNLength(reader);
|
||
byte[] exponent = new byte[exponentSize];
|
||
reader.Read(exponent, 0, exponent.Length);
|
||
|
||
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
|
||
RSAParameters RSAKeyInfo = new RSAParameters();
|
||
RSAKeyInfo.Modulus = modulus;
|
||
RSAKeyInfo.Exponent = exponent;
|
||
RSA.ImportParameters(RSAKeyInfo);
|
||
return RSA;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return null;
|
||
}
|
||
|
||
public static int ReadASNLength(BinaryReader reader)
|
||
{
|
||
//Note: this method only reads lengths up to 4 bytes long as
|
||
//this is satisfactory for the majority of situations.
|
||
int length = reader.ReadByte();
|
||
if ((length & 0x00000080) == 0x00000080) //is the length greater than 1 byte
|
||
{
|
||
int count = length & 0x0000000f;
|
||
byte[] lengthBytes = new byte[4];
|
||
reader.Read(lengthBytes, 4 - count, count);
|
||
Array.Reverse(lengthBytes); //
|
||
length = BitConverter.ToInt32(lengthBytes, 0);
|
||
}
|
||
return length;
|
||
}
|
||
|
||
|
||
public static string EncodeBase64(string code)
|
||
{
|
||
return EncodeBase64("utf-8", code);
|
||
}
|
||
|
||
public static string DecodeBase64(string code)
|
||
{
|
||
return DecodeBase64("utf-8", code);
|
||
}
|
||
|
||
public static string EncodeBase64(string code_type, string code)
|
||
{
|
||
string encode = string.Empty;
|
||
byte[] bytes = Encoding.GetEncoding(code_type).GetBytes(code);
|
||
try
|
||
{
|
||
encode = Convert.ToBase64String(bytes);
|
||
}
|
||
catch
|
||
{
|
||
encode = code;
|
||
}
|
||
return encode;
|
||
}
|
||
|
||
public static string DecodeBase64(string code_type, string code)
|
||
{
|
||
string decode = string.Empty;
|
||
try
|
||
{
|
||
byte[] bytes = Convert.FromBase64String(code);
|
||
decode = Encoding.GetEncoding(code_type).GetString(bytes);
|
||
}
|
||
catch
|
||
{
|
||
decode = code;
|
||
}
|
||
return decode;
|
||
}
|
||
|
||
////测试代码:
|
||
|
||
//static void Main(string[] args)
|
||
//{
|
||
// string encodeString = RSAHelper.Encrypt("1234567");
|
||
// Console.WriteLine(encodeString);
|
||
|
||
|
||
// string decode = RSAHelper.Decrypt(encodeString);
|
||
// Console.WriteLine(decode);
|
||
|
||
// Console.ReadLine();
|
||
//}
|
||
|
||
}
|
||
}
|