Last active
February 7, 2025 15:28
-
-
Save GaiaAnn/29071961482462ff5334a121bd103166 to your computer and use it in GitHub Desktop.
RSA Encrypt/Decrypt & Sing/VerifySign C# sample
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private static string Encrypt(string publicKey, string content) | |
{ | |
RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(); | |
//Get publicKey information | |
RSAParameters parameters = ConvertFromPublicKey(publicKey); | |
rsa.ImportParameters(parameters); | |
//Convert to UTF8 bytes | |
var content_utf = rsa.Encrypt(Encoding.UTF8.GetBytes(content), false); | |
//Convert to Base64String | |
var encryptString = Convert.ToBase64String(content_utf); | |
return encryptString; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private static string Decrypt(string privateKey,string encryptContent) | |
{ | |
//Get privateKey information | |
RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(Convert.FromBase64String(privateKey)); | |
//Convert Base64String Into byte then do Decrypt | |
var desContent = rsa.Decrypt(Convert.FromBase64String(encryptContent), false); | |
//return UTF string result | |
return Encoding.UTF8.GetString(desContent); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static string Sign(string content, string pvKey, string input_charset) | |
{ | |
byte[] Data = Encoding.GetEncoding(input_charset).GetBytes(content); | |
byte[] privatekey; | |
privatekey = Convert.FromBase64String(pvKey); | |
RSACryptoServiceProvider rsa = DecodeRSAPrivateKey(privatekey); | |
SHA1 sh = new SHA1CryptoServiceProvider(); | |
byte[] signData = rsa.SignData(Data, sh); | |
return Convert.ToBase64String(signData); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static bool VerifySign(string content, string signedString, string publicKey, string input_charset) | |
{ | |
signedString = signedString.Replace("*", "+"); | |
signedString = signedString.Replace("-", "/"); | |
return JiJianverify(content, signedString, publicKey, input_charset); | |
} | |
/// <summary> | |
/// verify sign | |
/// </summary> | |
/// <param name="content"></param> | |
/// <param name="signedString"></param> | |
/// <param name="publicKey"></param> | |
/// <param name="input_charset"></param> | |
public static bool JiJianverify(string content, string signedString, string publicKey, string input_charset) | |
{ | |
bool result = false; | |
byte[] Data = Encoding.GetEncoding(input_charset).GetBytes(content); | |
byte[] data = Convert.FromBase64String(signedString); | |
RSAParameters paraPub = ConvertFromPublicKey(publicKey); | |
RSACryptoServiceProvider rsaPub = new RSACryptoServiceProvider(); | |
rsaPub.ImportParameters(paraPub); | |
SHA1 sh = new SHA1CryptoServiceProvider(); | |
result = rsaPub.VerifyData(Data, sh, data); | |
return result; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey) | |
{ | |
byte[] MODULUS, E, D, P, Q, DP, DQ, IQ; | |
// --------- Set up stream to decode the asn.1 encoded RSA private key ------ | |
MemoryStream mem = new MemoryStream(privkey); | |
BinaryReader binr = new BinaryReader(mem); //wrap Memory Stream with BinaryReader for easy reading | |
byte bt = 0; | |
ushort twobytes = 0; | |
int elems = 0; | |
try | |
{ | |
twobytes = binr.ReadUInt16(); | |
if (twobytes == 0x8130) //data read as little endian order (actual data order for Sequence is 30 81) | |
binr.ReadByte(); //advance 1 byte | |
else if (twobytes == 0x8230) | |
binr.ReadInt16(); //advance 2 bytes | |
else | |
return null; | |
twobytes = binr.ReadUInt16(); | |
if (twobytes != 0x0102) //version number | |
return null; | |
bt = binr.ReadByte(); | |
if (bt != 0x00) | |
return null; | |
//------ all private key components are Integer sequences ---- | |
elems = GetIntegerSize(binr); | |
MODULUS = binr.ReadBytes(elems); | |
elems = GetIntegerSize(binr); | |
E = binr.ReadBytes(elems); | |
elems = GetIntegerSize(binr); | |
D = binr.ReadBytes(elems); | |
elems = GetIntegerSize(binr); | |
P = binr.ReadBytes(elems); | |
elems = GetIntegerSize(binr); | |
Q = binr.ReadBytes(elems); | |
elems = GetIntegerSize(binr); | |
DP = binr.ReadBytes(elems); | |
elems = GetIntegerSize(binr); | |
DQ = binr.ReadBytes(elems); | |
elems = GetIntegerSize(binr); | |
IQ = binr.ReadBytes(elems); | |
// ------- create RSACryptoServiceProvider instance and initialize with public key ----- | |
RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); | |
RSAParameters RSAparams = new RSAParameters(); | |
RSAparams.Modulus = MODULUS; | |
RSAparams.Exponent = E; | |
RSAparams.D = D; | |
RSAparams.P = P; | |
RSAparams.Q = Q; | |
RSAparams.DP = DP; | |
RSAparams.DQ = DQ; | |
RSAparams.InverseQ = IQ; | |
RSA.ImportParameters(RSAparams); | |
return RSA; | |
} | |
catch (Exception) | |
{ | |
return null; | |
} | |
finally { binr.Close(); } | |
} | |
private static int GetIntegerSize(BinaryReader binr) | |
{ | |
byte bt = 0; | |
byte lowbyte = 0x00; | |
byte highbyte = 0x00; | |
int count = 0; | |
bt = binr.ReadByte(); | |
if (bt != 0x02) //expect integer | |
return 0; | |
bt = binr.ReadByte(); | |
if (bt == 0x81) | |
count = binr.ReadByte(); // data size in next byte | |
else | |
if (bt == 0x82) | |
{ | |
highbyte = binr.ReadByte(); // data size in next 2 bytes | |
lowbyte = binr.ReadByte(); | |
byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; | |
count = BitConverter.ToInt32(modint, 0); | |
} | |
else | |
{ | |
count = bt; // we already have the data size | |
} | |
while (binr.ReadByte() == 0x00) | |
{ //remove high order zeros in data | |
count -= 1; | |
} | |
binr.BaseStream.Seek(-1, SeekOrigin.Current); //last ReadByte wasn't a removed zero, so back up a byte | |
return count; | |
} | |
private static RSAParameters ConvertFromPublicKey(string publicKey) | |
{ | |
byte[] keyData = Convert.FromBase64String(publicKey); | |
if (keyData.Length < 162) | |
{ | |
throw new ArgumentException("[PublicKey] .pem file content is incorrect."); | |
} | |
RsaKeyParameters publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(keyData); | |
RSAParameters para = new RSAParameters(); | |
para.Modulus = publicKeyParam.Modulus.ToByteArrayUnsigned(); | |
para.Exponent = publicKeyParam.Exponent.ToByteArrayUnsigned(); | |
return para; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment