/// <summary> /// 根据十六进制还是base64来进行RSA的初始化 /// </summary> /// <param name="privateKey"></param> /// <returns></returns> public static RSA CreateRsaProviderFromPrivateKey(byte[] privateKeyByte) { using (var rsa = RSA.Create()) { var rsaParameters = new RSAParameters(); using (BinaryReader binr = new BinaryReader(new MemoryStream(privateKeyByte))) { 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()"); } rsaParameters.Modulus = binr.ReadBytes(SecretAlg.GetIntegerSize(binr)); rsaParameters.Exponent = binr.ReadBytes(SecretAlg.GetIntegerSize(binr)); rsaParameters.D = binr.ReadBytes(SecretAlg.GetIntegerSize(binr)); rsaParameters.P = binr.ReadBytes(SecretAlg.GetIntegerSize(binr)); rsaParameters.Q = binr.ReadBytes(SecretAlg.GetIntegerSize(binr)); rsaParameters.DP = binr.ReadBytes(SecretAlg.GetIntegerSize(binr)); rsaParameters.DQ = binr.ReadBytes(SecretAlg.GetIntegerSize(binr)); rsaParameters.InverseQ = binr.ReadBytes(SecretAlg.GetIntegerSize(binr)); } rsa.ImportParameters(rsaParameters); return(rsa); } }
/// <summary> /// 根据十六进制还是base64来进行RSA的初始化 /// </summary> /// <param name="publicKeyString"></param> /// <returns></returns> public static RSA CreateRsaProviderFromPublicKey(byte[] publicKeyByte) { // encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1" byte[] seqOid = { 0x30, 0x0D, 0x06, 0x09, 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01, 0x05, 0x00 }; byte[] seq = new byte[15]; // --------- Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob ------ using (MemoryStream mem = new MemoryStream(publicKeyByte)) { 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 (!SecretAlg.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); } twobytes = binr.ReadUInt16(); byte lowbyte = 0x00; byte highbyte = 0x00; 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 ----- using (var rsa = RSA.Create()) { RSAParameters rsaKeyInfo = new RSAParameters { Modulus = modulus, Exponent = exponent }; rsa.ImportParameters(rsaKeyInfo); return(rsa); } } } }