public RSACrypto(string privateKey, string publicKey = null) { if (!string.IsNullOrEmpty(privateKey)) { _privateKeyRsaProvider= CreateRsaProviderFromPrivateKey(privateKey); }
if (!string.IsNullOrEmpty(publicKey)) { _publicKeyRsaProvider= CreateRsaProviderFromPublicKey(publicKey); } }
public string Decrypt(string cipherText) { if (_privateKeyRsaProvider == null) { throw new Exception("_privateKeyRsaProvider is null"); } return Encoding.UTF8.GetString(_privateKeyRsaProvider.Decrypt(System.Convert.FromBase64String(cipherText), false)); }
public string Encrypt(string text) { if (_publicKeyRsaProvider == null) { throw new Exception("_publicKeyRsaProvider is null"); } return Convert.ToBase64String(_publicKeyRsaProvider.Encrypt(Encoding.UTF8.GetBytes(text), false)); }
private RSACryptoServiceProvider CreateRsaProviderFromPrivateKey(string privateKey) { var privateKeyBits = System.Convert.FromBase64String(privateKey);
var RSA = new RSACryptoServiceProvider(); var RSAparams = new RSAParameters();
using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyBits))) { byte bt = 0; ushort twobytes = 0; twobytes= binr.ReadUInt16(); if (twobytes == 0x8130) binr.ReadByte(); else if (twobytes == 0x8230) binr.ReadInt16(); else throw new Exception("Unexpected value read binr.ReadUInt16()");
twobytes= binr.ReadUInt16(); if (twobytes != 0x0102) throw new Exception("Unexpected version");
bt= binr.ReadByte(); if (bt != 0x00) throw new Exception("Unexpected value read binr.ReadByte()");
// --------- Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob ------ using (MemoryStream mem = new MemoryStream(x509key)) { using (BinaryReader binr = new BinaryReader(mem)) //wrap Memory Stream with BinaryReader for easy reading { byte bt = 0; ushort twobytes = 0;
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;
seq= binr.ReadBytes(15); //read the Sequence OID if (!CompareBytearrays(seq, SeqOID)) //make sure Sequence for OID is correct return null;
twobytes= binr.ReadUInt16(); if (twobytes == 0x8103) //data read as little endian order (actual data order for Bit String is 03 81) binr.ReadByte(); //advance 1 byte else if (twobytes == 0x8203) binr.ReadInt16(); //advance 2 bytes else return null;
bt= binr.ReadByte(); if (bt != 0x00) //expect null byte next return null;
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;
if (twobytes == 0x8102) //data read as little endian order (actual data order for Integer is 02 81) lowbyte = binr.ReadByte(); // read next bytes which is bytes in modulus else if (twobytes == 0x8202) { highbyte= binr.ReadByte(); //advance 2 bytes lowbyte = binr.ReadByte(); } else return null; byte[] modint = { lowbyte, highbyte, 0x00, 0x00 }; //reverse byte order since asn.1 key uses big endian order int modsize = BitConverter.ToInt32(modint, 0);
int firstbyte = binr.PeekChar(); if (firstbyte == 0x00) { //if first byte (highest order) of modulus is zero, don"t include it binr.ReadByte(); //skip this null byte modsize -= 1; //reduce modulus buffer size by 1 }
byte[] modulus = binr.ReadBytes(modsize); //read the modulus bytes
if (binr.ReadByte() != 0x02) //expect an Integer for the exponent data return null; int expbytes = (int)binr.ReadByte(); // should only need one byte for actual exponent data (for all useful values) byte[] exponent = binr.ReadBytes(expbytes);
// ------- create RSACryptoServiceProvider instance and initialize with public key ----- RSACryptoServiceProvider RSA = new RSACryptoServiceProvider(); RSAParameters RSAKeyInfo= new RSAParameters(); RSAKeyInfo.Modulus= modulus; RSAKeyInfo.Exponent= exponent; RSA.ImportParameters(RSAKeyInfo);
return RSA; }
} }
private bool CompareBytearrays(byte[] a, byte[] b) { if (a.Length != b.Length) return false; int i = 0; foreach (byte c in a) { if (c != b[i]) return false; i++; } return true; } }到此结束了。本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-08/134155.htm