一、產生密鑰:java
private static void CreateKey() { using (RSACryptoServiceProvider rsa = new RSACryptoServiceProvider()) { string publicKey = rsa.ToXmlString(false); // 公鑰 string privateKey = rsa.ToXmlString(true); // 私鑰 } }
這裏產生的密鑰是xml格式的,這也是.net的rsa的密鑰格式。但有時候在.net項目中,咱們只有java格式的密鑰,具體的來講密鑰就是一個字符串,這時候須要將其轉換爲xml格式的。app
//公鑰格式的轉換 public static string RsaPublicKeyToXml(string publicKey) { try { if (string.IsNullOrWhiteSpace(publicKey)) return ""; if (publicKey.Contains("<RSAKeyValue>")) return publicKey; RsaKeyParameters publicKeyParam; //嘗試進行java格式的密鑰讀取 try { publicKeyParam = (RsaKeyParameters)PublicKeyFactory.CreateKey(Convert.FromBase64String(publicKey)); } catch { publicKeyParam = null; } //非java格式密鑰進行pem格式的密鑰讀取 if (publicKeyParam == null) { try { var pemKey = publicKey; if (!pemKey.Contains("BEGIN RSA PRIVATE KEY")) { pemKey = @"-----BEGIN RSA PRIVATE KEY----- " + publicKey + @" -----END RSA PRIVATE KEY-----"; } var array = Encoding.ASCII.GetBytes(pemKey); var stream = new MemoryStream(array); var reader = new StreamReader(stream); var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(reader); publicKeyParam = (RsaKeyParameters)pemReader.ReadObject(); } catch { publicKeyParam = null; } } //若是都解析失敗,則返回原串 if (publicKeyParam == null) return publicKey; //輸出XML格式密鑰 return string.Format( "<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>", Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned()) ); } catch (Exception) { return "error"; } }
//私鑰格式轉換 public static string RsaPrivateKeyToXml(string privateKey) { try { if (string.IsNullOrWhiteSpace(privateKey)) return ""; if (privateKey.Contains("<RSAKeyValue>")) return privateKey; RsaPrivateCrtKeyParameters privateKeyParam; //嘗試進行java格式的密鑰讀取 try { privateKeyParam = (RsaPrivateCrtKeyParameters)PrivateKeyFactory.CreateKey(Convert.FromBase64String(privateKey)); } catch { privateKeyParam = null; } //非java格式密鑰進行pem格式的密鑰讀取 if (privateKeyParam == null) { try { var pemKey = privateKey; if (!pemKey.Contains("BEGIN RSA PRIVATE KEY")) { pemKey = @"-----BEGIN RSA PRIVATE KEY----- " + privateKey + @" -----END RSA PRIVATE KEY-----"; } var array = Encoding.ASCII.GetBytes(pemKey); var stream = new MemoryStream(array); var reader = new StreamReader(stream); var pemReader = new Org.BouncyCastle.OpenSsl.PemReader(reader); var keyPair = (AsymmetricCipherKeyPair)pemReader.ReadObject(); privateKeyParam = (RsaPrivateCrtKeyParameters)keyPair.Private; } catch { privateKeyParam = null; } } //若是都解析失敗,則返回原串 if (privateKeyParam == null) return privateKey; //輸出XML格式密鑰 return string.Format( "<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent><P>{2}</P><Q>{3}</Q><DP>{4}</DP><DQ>{5}</DQ><InverseQ>{6}</InverseQ><D>{7}</D></RSAKeyValue>", Convert.ToBase64String(privateKeyParam.Modulus.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.PublicExponent.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.P.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Q.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DP.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.DQ.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.QInv.ToByteArrayUnsigned()), Convert.ToBase64String(privateKeyParam.Exponent.ToByteArrayUnsigned()) ); } catch (Exception) { throw PayException.New("RSA私鑰密鑰格式轉換失敗"); } }
二、公鑰加密,私鑰解密(包括超長字符串的分段加密解密)ide
public static string RsaEncrypt(string rawInput, string publicKey) { if (string.IsNullOrEmpty(rawInput)) { return string.Empty; } if (string.IsNullOrWhiteSpace(publicKey)) { throw new ArgumentException("Invalid Public Key"); } using (var rsaProvider = new RSACryptoServiceProvider()) { var inputBytes = Encoding.UTF8.GetBytes(rawInput);//有含義的字符串轉化爲字節流 rsaProvider.FromXmlString(publicKey);//載入公鑰 int bufferSize = (rsaProvider.KeySize / 8) - 11;//單塊最大長度 var buffer = new byte[bufferSize]; using (MemoryStream inputStream = new MemoryStream(inputBytes), outputStream = new MemoryStream()) { while (true) { //分段加密 int readSize = inputStream.Read(buffer, 0, bufferSize); if (readSize <= 0) { break; } var temp = new byte[readSize]; Array.Copy(buffer, 0, temp, 0, readSize); var encryptedBytes = rsaProvider.Encrypt(temp, false); outputStream.Write(encryptedBytes, 0, encryptedBytes.Length); } return Convert.ToBase64String(outputStream.ToArray());//轉化爲字節流方便傳輸 } } } public static string RsaDecrypt(string encryptedInput, string privateKey) { if (string.IsNullOrEmpty(encryptedInput)) { return string.Empty; } if (string.IsNullOrWhiteSpace(privateKey)) { throw new ArgumentException("Invalid Private Key"); } using (var rsaProvider = new RSACryptoServiceProvider()) { var inputBytes = Convert.FromBase64String(encryptedInput); rsaProvider.FromXmlString(privateKey); int bufferSize = rsaProvider.KeySize / 8; var buffer = new byte[bufferSize]; using (MemoryStream inputStream = new MemoryStream(inputBytes), outputStream = new MemoryStream()) { while (true) { int readSize = inputStream.Read(buffer, 0, bufferSize); if (readSize <= 0) { break; } var temp = new byte[readSize]; Array.Copy(buffer, 0, temp, 0, readSize); var rawBytes = rsaProvider.Decrypt(temp, false); outputStream.Write(rawBytes, 0, rawBytes.Length); } return Encoding.UTF8.GetString(outputStream.ToArray()); } } }
三、私鑰加密,公鑰解密(包括超長字符串的分段加密解密)編碼
/// <summary> /// RSA加密 使用私鑰加密 /// </summary> /// <param name="byteData"></param> /// <param name="key"></param> /// <returns></returns> private static string RSAEncrypt(string data, string key) { byte[] byteData = Encoding.UTF8.GetBytes(data); var privateRsa = GetRsaCryptoFromXml(key); //轉換密鑰 下面的DotNetUtilities來自Org.BouncyCastle.Security var keyPair = DotNetUtilities.GetKeyPair(privateRsa); var c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding"); c.Init(true, keyPair.Private);//取私鑰(true爲加密) int bufferSize = (privateRsa.KeySize / 8) - 11;//單塊最大長度 var buffer = new byte[bufferSize]; using (MemoryStream inputStream = new MemoryStream(byteData), outputStream = new MemoryStream()) { while (true) { //分段加密 int readSize = inputStream.Read(buffer, 0, bufferSize); if (readSize <= 0) { break; } var temp = new byte[readSize]; Array.Copy(buffer, 0, temp, 0, readSize); //var encryptedBytes = rsaProvider.Encrypt(temp, false); var encryptedBytes = c.DoFinal(temp); outputStream.Write(encryptedBytes, 0, encryptedBytes.Length); } return Convert.ToBase64String( outputStream.ToArray());//轉化爲字節流方便傳輸 } } /// <summary> /// RSA解密 使用公鑰解密 /// </summary> /// <param name="byteData"></param> /// <param name="key"></param> /// <returns></returns> private static string RSADecrypt(string data, string key) { byte[] byteData= Convert.FromBase64String(data); var privateRsa = GetRsaCryptoFromXml(key); //轉換密鑰 var keyPair = DotNetUtilities.GetRsaPublicKey(privateRsa); var c = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding"); c.Init(false, keyPair);//取公鑰(false爲解密) using (MemoryStream inputStream = new MemoryStream(byteData), outputStream = new MemoryStream()) { int restLength = byteData.Length; while (restLength > 0) { int readLength = restLength < 128 ? restLength : 128; restLength = restLength - readLength; byte[] readBytes = new byte[readLength]; inputStream.Read(readBytes, 0, readLength); byte[] append = c.DoFinal(readBytes); outputStream.Write(append, 0, append.Length); } //注意,這裏不必定就是用utf8的編碼方式,這個主要看加密的時候用的什麼編碼方式 return Encoding.UTF8.GetString(outputStream.ToArray()); } }