mirror of
https://github.com/tym1116/BH3.git
synced 2025-12-14 07:24:44 +01:00
331 lines
8.1 KiB
C#
331 lines
8.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Security.Cryptography;
|
|
using System.Text;
|
|
|
|
namespace Com.Alipay
|
|
{
|
|
public sealed class RSAFromPkcs8
|
|
{
|
|
public static string sign(string content, string privateKey, string input_charset)
|
|
{
|
|
Encoding encoding = Encoding.GetEncoding(input_charset);
|
|
byte[] bytes = encoding.GetBytes(content);
|
|
RSACryptoServiceProvider rSACryptoServiceProvider = DecodePemPrivateKey(privateKey);
|
|
SHA1 halg = new SHA1CryptoServiceProvider();
|
|
byte[] inArray = rSACryptoServiceProvider.SignData(bytes, halg);
|
|
return Convert.ToBase64String(inArray);
|
|
}
|
|
|
|
public static bool verify(string content, string signedString, string publicKey, string input_charset)
|
|
{
|
|
bool flag = false;
|
|
Encoding encoding = Encoding.GetEncoding(input_charset);
|
|
byte[] bytes = encoding.GetBytes(content);
|
|
byte[] signature = Convert.FromBase64String(signedString);
|
|
RSAParameters parameters = ConvertFromPublicKey(publicKey);
|
|
RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
|
|
rSACryptoServiceProvider.ImportParameters(parameters);
|
|
SHA1 halg = new SHA1CryptoServiceProvider();
|
|
return rSACryptoServiceProvider.VerifyData(bytes, halg, signature);
|
|
}
|
|
|
|
public static string decryptData(string resData, string privateKey, string input_charset)
|
|
{
|
|
byte[] array = Convert.FromBase64String(resData);
|
|
List<byte> list = new List<byte>();
|
|
for (int i = 0; i < array.Length / 128; i++)
|
|
{
|
|
byte[] array2 = new byte[128];
|
|
for (int j = 0; j < 128; j++)
|
|
{
|
|
array2[j] = array[j + 128 * i];
|
|
}
|
|
list.AddRange(decrypt(array2, privateKey, input_charset));
|
|
}
|
|
byte[] array3 = list.ToArray();
|
|
char[] array4 = new char[Encoding.GetEncoding(input_charset).GetCharCount(array3, 0, array3.Length)];
|
|
Encoding.GetEncoding(input_charset).GetChars(array3, 0, array3.Length, array4, 0);
|
|
return new string(array4);
|
|
}
|
|
|
|
private static byte[] decrypt(byte[] data, string privateKey, string input_charset)
|
|
{
|
|
RSACryptoServiceProvider rSACryptoServiceProvider = DecodePemPrivateKey(privateKey);
|
|
return rSACryptoServiceProvider.Decrypt(data, false);
|
|
}
|
|
|
|
private static RSACryptoServiceProvider DecodePemPrivateKey(string pemstr)
|
|
{
|
|
byte[] array = Convert.FromBase64String(pemstr);
|
|
if (array != null)
|
|
{
|
|
return DecodePrivateKeyInfo(array);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static RSACryptoServiceProvider DecodePrivateKeyInfo(byte[] pkcs8)
|
|
{
|
|
byte[] b = new byte[15]
|
|
{
|
|
48, 13, 6, 9, 42, 134, 72, 134, 247, 13,
|
|
1, 1, 1, 5, 0
|
|
};
|
|
byte[] array = new byte[15];
|
|
MemoryStream memoryStream = new MemoryStream(pkcs8);
|
|
int num = (int)memoryStream.Length;
|
|
BinaryReader binaryReader = new BinaryReader(memoryStream);
|
|
byte b2 = 0;
|
|
ushort num2 = 0;
|
|
try
|
|
{
|
|
switch (binaryReader.ReadUInt16())
|
|
{
|
|
case 33072:
|
|
binaryReader.ReadByte();
|
|
break;
|
|
case 33328:
|
|
binaryReader.ReadInt16();
|
|
break;
|
|
default:
|
|
return null;
|
|
}
|
|
b2 = binaryReader.ReadByte();
|
|
if (b2 != 2)
|
|
{
|
|
return null;
|
|
}
|
|
num2 = binaryReader.ReadUInt16();
|
|
if (num2 != 1)
|
|
{
|
|
return null;
|
|
}
|
|
array = binaryReader.ReadBytes(15);
|
|
if (!CompareBytearrays(array, b))
|
|
{
|
|
return null;
|
|
}
|
|
b2 = binaryReader.ReadByte();
|
|
if (b2 != 4)
|
|
{
|
|
return null;
|
|
}
|
|
switch (binaryReader.ReadByte())
|
|
{
|
|
case 129:
|
|
binaryReader.ReadByte();
|
|
break;
|
|
case 130:
|
|
binaryReader.ReadUInt16();
|
|
break;
|
|
}
|
|
byte[] privkey = binaryReader.ReadBytes((int)(num - memoryStream.Position));
|
|
return DecodeRSAPrivateKey(privkey);
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
binaryReader.Close();
|
|
}
|
|
}
|
|
|
|
private static bool CompareBytearrays(byte[] a, byte[] b)
|
|
{
|
|
if (a.Length != b.Length)
|
|
{
|
|
return false;
|
|
}
|
|
int num = 0;
|
|
foreach (byte b2 in a)
|
|
{
|
|
if (b2 != b[num])
|
|
{
|
|
return false;
|
|
}
|
|
num++;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
private static RSACryptoServiceProvider DecodeRSAPrivateKey(byte[] privkey)
|
|
{
|
|
MemoryStream input = new MemoryStream(privkey);
|
|
BinaryReader binaryReader = new BinaryReader(input);
|
|
byte b = 0;
|
|
ushort num = 0;
|
|
int num2 = 0;
|
|
try
|
|
{
|
|
switch (binaryReader.ReadUInt16())
|
|
{
|
|
case 33072:
|
|
binaryReader.ReadByte();
|
|
break;
|
|
case 33328:
|
|
binaryReader.ReadInt16();
|
|
break;
|
|
default:
|
|
return null;
|
|
}
|
|
num = binaryReader.ReadUInt16();
|
|
if (num != 258)
|
|
{
|
|
return null;
|
|
}
|
|
if (binaryReader.ReadByte() != 0)
|
|
{
|
|
return null;
|
|
}
|
|
num2 = GetIntegerSize(binaryReader);
|
|
byte[] modulus = binaryReader.ReadBytes(num2);
|
|
num2 = GetIntegerSize(binaryReader);
|
|
byte[] exponent = binaryReader.ReadBytes(num2);
|
|
num2 = GetIntegerSize(binaryReader);
|
|
byte[] d = binaryReader.ReadBytes(num2);
|
|
num2 = GetIntegerSize(binaryReader);
|
|
byte[] p = binaryReader.ReadBytes(num2);
|
|
num2 = GetIntegerSize(binaryReader);
|
|
byte[] q = binaryReader.ReadBytes(num2);
|
|
num2 = GetIntegerSize(binaryReader);
|
|
byte[] dP = binaryReader.ReadBytes(num2);
|
|
num2 = GetIntegerSize(binaryReader);
|
|
byte[] dQ = binaryReader.ReadBytes(num2);
|
|
num2 = GetIntegerSize(binaryReader);
|
|
byte[] inverseQ = binaryReader.ReadBytes(num2);
|
|
RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
|
|
rSACryptoServiceProvider.ImportParameters(new RSAParameters
|
|
{
|
|
Modulus = modulus,
|
|
Exponent = exponent,
|
|
D = d,
|
|
P = p,
|
|
Q = q,
|
|
DP = dP,
|
|
DQ = dQ,
|
|
InverseQ = inverseQ
|
|
});
|
|
return rSACryptoServiceProvider;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
binaryReader.Close();
|
|
}
|
|
}
|
|
|
|
private static int GetIntegerSize(BinaryReader binr)
|
|
{
|
|
byte b = 0;
|
|
byte b2 = 0;
|
|
byte b3 = 0;
|
|
int num = 0;
|
|
b = binr.ReadByte();
|
|
if (b != 2)
|
|
{
|
|
return 0;
|
|
}
|
|
b = binr.ReadByte();
|
|
switch (b)
|
|
{
|
|
case 129:
|
|
num = binr.ReadByte();
|
|
break;
|
|
case 130:
|
|
{
|
|
b3 = binr.ReadByte();
|
|
b2 = binr.ReadByte();
|
|
byte[] value = new byte[4] { b2, b3, 0, 0 };
|
|
num = BitConverter.ToInt32(value, 0);
|
|
break;
|
|
}
|
|
default:
|
|
num = b;
|
|
break;
|
|
}
|
|
while (binr.ReadByte() == 0)
|
|
{
|
|
num--;
|
|
}
|
|
binr.BaseStream.Seek(-1L, SeekOrigin.Current);
|
|
return num;
|
|
}
|
|
|
|
private static RSAParameters ConvertFromPublicKey(string pemFileConent)
|
|
{
|
|
byte[] array = Convert.FromBase64String(pemFileConent);
|
|
if (array.Length < 162)
|
|
{
|
|
throw new ArgumentException("pem file content is incorrect.");
|
|
}
|
|
byte[] array2 = new byte[128];
|
|
byte[] array3 = new byte[3];
|
|
Array.Copy(array, 29, array2, 0, 128);
|
|
Array.Copy(array, 159, array3, 0, 3);
|
|
return new RSAParameters
|
|
{
|
|
Modulus = array2,
|
|
Exponent = array3
|
|
};
|
|
}
|
|
|
|
private static RSAParameters ConvertFromPrivateKey(string pemFileConent)
|
|
{
|
|
byte[] array = Convert.FromBase64String(pemFileConent);
|
|
if (array.Length < 609)
|
|
{
|
|
throw new ArgumentException("pem file content is incorrect.");
|
|
}
|
|
int num = 11;
|
|
byte[] array2 = new byte[128];
|
|
Array.Copy(array, num, array2, 0, 128);
|
|
num += 128;
|
|
num += 2;
|
|
byte[] array3 = new byte[3];
|
|
Array.Copy(array, num, array3, 0, 3);
|
|
num += 3;
|
|
num += 4;
|
|
byte[] array4 = new byte[128];
|
|
Array.Copy(array, num, array4, 0, 128);
|
|
num += 128;
|
|
num += ((array[num + 1] != 64) ? 3 : 2);
|
|
byte[] array5 = new byte[64];
|
|
Array.Copy(array, num, array5, 0, 64);
|
|
num += 64;
|
|
num += ((array[num + 1] != 64) ? 3 : 2);
|
|
byte[] array6 = new byte[64];
|
|
Array.Copy(array, num, array6, 0, 64);
|
|
num += 64;
|
|
num += ((array[num + 1] != 64) ? 3 : 2);
|
|
byte[] array7 = new byte[64];
|
|
Array.Copy(array, num, array7, 0, 64);
|
|
num += 64;
|
|
num += ((array[num + 1] != 64) ? 3 : 2);
|
|
byte[] array8 = new byte[64];
|
|
Array.Copy(array, num, array8, 0, 64);
|
|
num += 64;
|
|
num += ((array[num + 1] != 64) ? 3 : 2);
|
|
byte[] array9 = new byte[64];
|
|
Array.Copy(array, num, array9, 0, 64);
|
|
return new RSAParameters
|
|
{
|
|
Modulus = array2,
|
|
Exponent = array3,
|
|
D = array4,
|
|
P = array5,
|
|
Q = array6,
|
|
DP = array7,
|
|
DQ = array8,
|
|
InverseQ = array9
|
|
};
|
|
}
|
|
}
|
|
}
|