可用的 .net core 支持 RSA 私钥加密工具类
首先说明 MS并不建议私钥加密,而且.net 于安全的考虑,RSACryptoServiceProvider类解密时只有同时拥有公钥和私钥才可以,原因是公钥是公开的,会被多人持有,这样的数据传输是不安全的。但是架不住有BouncyCastle这个第三方组件,也是可以实现的。只不过在.net core 2.2 下,没有了 RSACryptoServiceProvider,只好改用 System.Security.Cryptography.RSA 来实现 RSA 私钥加密
- #Const SUPPORT_PRIVATE_ENCRYPT = True
- Imports System.IO
- Imports System.Text
- Imports System.Security.Cryptography
- #If SUPPORT_PRIVATE_ENCRYPT Then
- Imports Org.BouncyCastle.Math
- Imports Org.BouncyCastle.Crypto
- Imports Org.BouncyCastle.Security
- Imports Org.BouncyCastle.Crypto.Parameters
- #End If
- ''' <summary>
- ''' RSA 加密解密辅助类
- ''' </summary>
- ''' <remarks></remarks>
- Public Class RSAHelper
- Private Shared _privateKey As String
- ''' <summary>
- ''' RSA私钥,包含公钥和私钥
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Shared ReadOnly Property PrivateKey As String
- Get
- Return _privateKey
- End Get
- End Property
- Private Shared _publicKey As String
- ''' <summary>
- ''' RSA公钥,只包含公钥
- ''' </summary>
- ''' <value></value>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Shared ReadOnly Property PublicKey As String
- Get
- Return _publicKey
- End Get
- End Property
- ''' <summary>
- ''' 创建RSA密钥对
- ''' </summary>
- ''' <param name="keySize">512,1024 ...</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Shared Function CreateRSAKey(Optional ByVal keySize As Int32 = ) As Boolean
- _privateKey = Nothing
- _publicKey = Nothing
- Try
- 'Dim provider As New RSACryptoServiceProvider(keySize)
- Dim provider = RSA.Create()
- provider.KeySize = keySize
- _privateKey = provider.ToXml(True)
- _publicKey = provider.ToXml(False)
- Console.WriteLine("max encrypt buffer size:{0}", (keySize / ) - )
- Console.WriteLine("max decrypt buffer size:{0}", keySize / )
- Console.WriteLine(provider.ToPem(True))
- Console.WriteLine()
- Console.WriteLine(provider.ToPem(False))
- Console.WriteLine(provider.ToXml(True))
- Console.WriteLine()
- Console.WriteLine(provider.ToXml(False))
- #If SUPPORT_PRIVATE_ENCRYPT Then
- '验证秘钥对
- provider.FromXml(_privateKey)
- Dim p = provider.ExportParameters(True)
- Dim rkpPrivate As New RsaKeyParameters(True, New BigInteger(, p.Modulus), New BigInteger(p.D))
- Dim rkpPublic As New RsaKeyParameters(False, New BigInteger(, p.Modulus), New BigInteger(p.Exponent))
- '密钥对有无效的概率,不报错的才可用
- #End If
- Return True
- Catch ex As Exception
- Debug.Print("CreateRSAKey({0}) failed, err:{1}", keySize, ex.Message)
- Return False
- End Try
- End Function
- Private Shared Function isKeyValid(ByVal key As String) As Boolean
- If String.IsNullOrEmpty(key) Then
- Return False
- End If
- If key.Trim().Length = Then
- Return False
- End If
- Return True
- End Function
- ''' <summary>
- ''' 公钥加密
- ''' </summary>
- ''' <param name="publicKey" >公钥(XML格式字符串)</param>
- ''' <param name="plaintext">待加密字符串,明文</param>
- ''' <returns></returns>
- Public Shared Function PublicKeyEncrypt(ByVal publicKey As String, plaintext As String) As String
- '默认只能使用[公钥]进行加密(想使用[公钥解密]可使用第三方组件BouncyCastle来实现)
- If String.IsNullOrEmpty(plaintext) Then
- Return String.Empty
- End If
- If Not isKeyValid(publicKey) Then
- Throw New ArgumentException("Invalid Public Key")
- End If
- '创建RSA对象并载入[公钥]
- Dim provider = RSA.Create
- provider.FromXml(publicKey)
- If (provider.KeySize / - ) <= plaintext.Length Then
- Throw New ArgumentException("plaintext is too long, try PublicKeyEncryptEx please")
- End If
- '对数据进行加密
- Dim publicValue() As Byte = provider.Encrypt(Encoding.UTF8.GetBytes(plaintext), RSAEncryptionPadding.Pkcs1)
- Dim ciphertext As String = Convert.ToBase64String(publicValue) '使用Base64将byte转换为string
- Return ciphertext
- End Function
- ''' <summary>
- ''' 私钥解密
- ''' </summary>
- ''' <param name="privateKey" >私钥(XML格式字符串)</param>
- ''' <param name="ciphertext">待解密字符串,密文</param>
- ''' <returns></returns>
- Public Shared Function PrivateKeyDecrypt(ByVal privateKey As String, ByVal ciphertext As String) As String
- '默认只能使用[私钥]进行解密(想使用[私钥加密]可使用第三方组件BouncyCastle来实现)
- If String.IsNullOrEmpty(ciphertext) Then
- Return String.Empty
- End If
- If Not isKeyValid(privateKey) Then
- Throw New ArgumentException("Invalid Private Key")
- End If
- '创建RSA对象并载入[私钥]
- Dim provider = RSA.Create
- provider.FromXml(privateKey)
- If (provider.KeySize / / ) <= ciphertext.Length / Then
- Throw New ArgumentException("ciphertext is too long, try PrivateKeyDecryptEx please")
- End If
- '对数据进行解密
- Dim privateValue() As Byte = provider.Decrypt(Convert.FromBase64String(ciphertext), RSAEncryptionPadding.Pkcs1) '使用Base64将string转换为byte
- Dim plaintext As String = Encoding.UTF8.GetString(privateValue)
- Return plaintext
- End Function
- ''' <summary>
- ''' 公钥加密
- ''' </summary>
- ''' <param name="publicKey">公钥(XML格式字符串)</param>
- ''' <param name="plaintext">待加密字符串,明文,长度不限</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Shared Function PublicKeyEncryptEx(ByVal publicKey As String, ByVal plaintext As String) As String
- If String.IsNullOrEmpty(plaintext) Then
- Return String.Empty
- End If
- If Not isKeyValid(publicKey) Then
- Throw New ArgumentException("Invalid Public Key")
- End If
- '载入公钥
- Dim provider = RSA.Create
- provider.FromXml(publicKey)
- Dim inputBytes = Encoding.UTF8.GetBytes(plaintext) '有含义的字符串转化为字节流
- Dim bufferSize As Integer = (provider.KeySize / ) - '单块最大长度
- Dim buffer = New Byte(bufferSize - ) {}
- Using inputStream As New MemoryStream(inputBytes), outputStream As New MemoryStream()
- Do
- Dim readSize As Integer = inputStream.Read(buffer, , bufferSize)
- If readSize <= Then
- Exit Do
- End If
- Dim temp = New Byte(readSize - ) {}
- Array.Copy(buffer, , temp, , readSize)
- Dim encryptedBytes = provider.Encrypt(temp, RSAEncryptionPadding.Pkcs1) 'False)
- outputStream.Write(encryptedBytes, , encryptedBytes.Length)
- Loop
- Return Convert.ToBase64String(outputStream.ToArray()) '转化为字节流方便传输
- End Using
- End Function
- ''' <summary>
- ''' 私钥解密
- ''' </summary>
- ''' <param name="privateKey">私钥(XML格式字符串)</param>
- ''' <param name="ciphertext">待解密字符串,密文,长度不限</param>
- ''' <returns></returns>
- ''' <remarks></remarks>
- Public Shared Function PrivateKeyDecryptEx(ByVal privateKey As String, ByVal ciphertext As String) As String
- If String.IsNullOrEmpty(ciphertext) Then
- Return String.Empty
- End If
- If Not isKeyValid(privateKey) Then
- Throw New ArgumentException("Invalid Private Key")
- End If
- '载入私钥
- Dim provider = RSA.Create
- provider.FromXml(privateKey)
- Dim inputBytes = Convert.FromBase64String(ciphertext)
- Dim bufferSize As Integer = provider.KeySize /
- Dim buffer = New Byte(bufferSize - ) {}
- Using inputStream As New MemoryStream(inputBytes), outputStream As New MemoryStream()
- Do
- Dim readSize As Integer = inputStream.Read(buffer, , bufferSize)
- If readSize <= Then
- Exit Do
- End If
- Dim temp = New Byte(readSize - ) {}
- Array.Copy(buffer, , temp, , readSize)
- Dim rawBytes = provider.Decrypt(temp, RSAEncryptionPadding.Pkcs1)
- outputStream.Write(rawBytes, , rawBytes.Length)
- Loop
- Return Encoding.UTF8.GetString(outputStream.ToArray())
- End Using
- End Function
- #Region " 依赖 BouncyCastle 实现私钥加密,公钥解密"
- #If SUPPORT_PRIVATE_ENCRYPT Then
- ''' <summary>
- ''' 私钥加密
- ''' </summary>
- ''' <param name="privateKey"> 私钥(XML格式字符串)</param>
- ''' <param name="plaintext"> 要加密的数据 </param>
- ''' <returns> 加密后的数据 </returns>
- Public Shared Function PrivateKeyEncrypt(ByVal privateKey As String, ByVal plaintext As String) As String
- If String.IsNullOrEmpty(plaintext) Then
- Return String.Empty
- End If
- If Not isKeyValid(privateKey) Then
- Throw New ArgumentException("Invalid Private Key")
- End If
- '加载私钥
- Dim provider = RSA.Create
- provider.FromXml(privateKey)
- Dim keyPair = DotNetCoreUtilities.GetKeyPair(provider)
- Dim c As IBufferedCipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding") '使用RSA/ECB/PKCS1Padding格式
- '第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
- c.Init(True, keyPair.Private)
- Dim DataToEncrypt() As Byte = Encoding.UTF8.GetBytes(plaintext)
- Dim outBytes() As Byte = c.DoFinal(DataToEncrypt) '加密
- Dim strBase64 As String = Convert.ToBase64String(outBytes)
- Return strBase64
- End Function
- ''' <summary>
- ''' 私钥加密
- ''' </summary>
- ''' <param name="privateKey"> 私钥(XML格式字符串)</param>
- ''' <param name="plaintext"> 要加密的数据,长度不限 </param>
- ''' <returns> 加密后的数据 </returns>
- Public Shared Function PrivateKeyEncryptEx(ByVal privateKey As String, ByVal plaintext As String) As String
- If String.IsNullOrEmpty(plaintext) Then
- Return String.Empty
- End If
- If Not isKeyValid(privateKey) Then
- Throw New ArgumentException("Invalid Private Key")
- End If
- '加载私钥
- Dim provider = RSA.Create 'As New RSACryptoServiceProvider()
- provider.FromXml(privateKey)
- Dim keyPair = DotNetCoreUtilities.GetKeyPair(provider)
- Dim c As IBufferedCipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding") '使用RSA/ECB/PKCS1Padding格式
- ''第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
- c.Init(True, keyPair.Private) ' keyPair.Private)
- Dim inputBytes = Encoding.UTF8.GetBytes(plaintext)
- Dim bufferSize As Integer = provider.KeySize / -
- Dim buffer = New Byte(bufferSize - ) {}
- Dim outputStream As New MemoryStream()
- Using inputStream As New MemoryStream(inputBytes)
- Do
- Dim readSize As Integer = inputStream.Read(buffer, , bufferSize)
- If readSize <= Then
- Exit Do
- End If
- Dim temp = New Byte(readSize - ) {}
- Array.Copy(buffer, , temp, , readSize)
- Dim rawBytes = c.DoFinal(temp)
- outputStream.Write(rawBytes, , rawBytes.Length)
- Loop
- End Using
- Return Convert.ToBase64String(outputStream.ToArray())
- End Function
- ''' <summary>
- ''' 公钥解密
- ''' </summary>
- ''' <param name="publicKey"> 公钥(XML格式字符串) </param>
- ''' <param name="ciphertext"> 要解密数据 </param>
- ''' <returns> 解密后的数据 </returns>
- Public Shared Function PublicKeyDecrypt(ByVal publicKey As String, ByVal ciphertext As String) As String
- If String.IsNullOrEmpty(ciphertext) Then
- Return String.Empty
- End If
- If Not isKeyValid(publicKey) Then
- Throw New ArgumentException("Invalid Public Key")
- End If
- '加载公钥
- Dim provider = RSA.Create
- provider.FromXml(publicKey)
- Dim keyParameter = DotNetCoreUtilities.GetKeyParmeter(provider.ToPem(False))
- Dim c As IBufferedCipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding")
- '第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
- c.Init(False, keyParameter)
- Dim DataToDecrypt() As Byte = Convert.FromBase64String(ciphertext)
- Dim outBytes() As Byte = c.DoFinal(DataToDecrypt) '解密
- Dim strDec As String = Encoding.UTF8.GetString(outBytes)
- Return strDec
- End Function
- ''' <summary>
- ''' 公钥解密
- ''' </summary>
- ''' <param name="publicKey"> 公钥(XML格式字符串) </param>
- ''' <param name="ciphertext"> 要解密数据,长度不限 </param>
- ''' <returns> 解密后的数据 </returns>
- Public Shared Function PublicKeyDecryptEx(ByVal publicKey As String, ByVal ciphertext As String) As String
- If String.IsNullOrEmpty(ciphertext) Then
- Return String.Empty
- End If
- If Not isKeyValid(publicKey) Then
- Throw New ArgumentException("Invalid Public Key")
- End If
- '加载公钥
- Dim provider = RSA.Create
- provider.FromXml(publicKey)
- Dim keyParameter = DotNetCoreUtilities.GetKeyParmeter(provider.ToPem(False))
- Dim c As IBufferedCipher = CipherUtilities.GetCipher("RSA/ECB/PKCS1Padding")
- '第一个参数为true表示加密,为false表示解密;第二个参数表示密钥
- c.Init(False, keyParameter)
- Dim inputBytes = Convert.FromBase64String(ciphertext)
- Dim bufferSize As Integer = provider.KeySize /
- Dim buffer = New Byte(bufferSize - ) {}
- Dim outputStream As New MemoryStream()
- Using inputStream As New MemoryStream(inputBytes)
- Do
- Dim readSize As Integer = inputStream.Read(buffer, , bufferSize)
- If readSize <= Then
- Exit Do
- End If
- Dim temp = New Byte(readSize - ) {}
- Array.Copy(buffer, , temp, , readSize)
- Dim rawBytes = c.DoFinal(temp)
- outputStream.Write(rawBytes, , rawBytes.Length)
- Loop
- End Using
- Return Encoding.UTF8.GetString(outputStream.ToArray())
- End Function
- #End If
- #End Region
- End Class
扩展方法
- Imports System.Security.Cryptography
- Imports System.Xml
- Imports Org.BouncyCastle.Crypto.Parameters
- Imports Org.BouncyCastle.Crypto
- Imports Org.BouncyCastle.Math
- Imports System.IO
- Imports Org.BouncyCastle.OpenSsl
- Imports Org.BouncyCastle.Security
- Imports System.Text
- Friend Module RsaExtention
- <System.Runtime.CompilerServices.Extension>
- Public Sub FromXml(ByVal rsa As RSA, ByVal xmlString As String)
- Dim parameters As New RSAParameters()
- Dim xmlDoc As New XmlDocument()
- xmlDoc.LoadXml(xmlString)
- If xmlDoc.DocumentElement.Name.Equals("RSAKeyValue") Then
- For Each node As XmlNode In xmlDoc.DocumentElement.ChildNodes
- Select Case node.Name
- Case "Modulus"
- parameters.Modulus = Convert.FromBase64String(node.InnerText)
- Case "Exponent"
- parameters.Exponent = Convert.FromBase64String(node.InnerText)
- Case "P"
- parameters.P = Convert.FromBase64String(node.InnerText)
- Case "Q"
- parameters.Q = Convert.FromBase64String(node.InnerText)
- Case "DP"
- parameters.DP = Convert.FromBase64String(node.InnerText)
- Case "DQ"
- parameters.DQ = Convert.FromBase64String(node.InnerText)
- Case "InverseQ"
- parameters.InverseQ = Convert.FromBase64String(node.InnerText)
- Case "D"
- parameters.D = Convert.FromBase64String(node.InnerText)
- End Select
- Next node
- Else
- Throw New Exception("Invalid XML RSA key.")
- End If
- rsa.ImportParameters(parameters)
- End Sub
- <System.Runtime.CompilerServices.Extension>
- Public Function ToXml(ByVal rsa As RSA, ByVal includePrivateParameters As Boolean) As String
- Dim parameters As RSAParameters = rsa.ExportParameters(includePrivateParameters)
- Dim ret As String
- If includePrivateParameters Then
- ret = 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(parameters.Modulus),
- Convert.ToBase64String(parameters.Exponent),
- Convert.ToBase64String(parameters.P),
- Convert.ToBase64String(parameters.Q),
- Convert.ToBase64String(parameters.DP),
- Convert.ToBase64String(parameters.DQ),
- Convert.ToBase64String(parameters.InverseQ),
- Convert.ToBase64String(parameters.D))
- Else
- ret = String.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
- Convert.ToBase64String(parameters.Modulus),
- Convert.ToBase64String(parameters.Exponent))
- End If
- Return formatXml(ret)
- End Function
- Private Function formatXml(ByVal sUnformattedXml As String) As String
- Dim xd As New XmlDocument()
- xd.LoadXml(sUnformattedXml)
- Dim sb As New StringBuilder()
- Dim sw As New StringWriter(sb)
- Dim xtw As XmlTextWriter = Nothing
- Try
- xtw = New XmlTextWriter(sw)
- xtw.Formatting = Formatting.Indented
- xtw.Indentation =
- xtw.IndentChar = Char.Parse(vbTab)
- xd.WriteTo(xtw)
- Finally
- If xtw IsNot Nothing Then
- xtw.Close()
- End If
- End Try
- Return sb.ToString()
- End Function
- <System.Runtime.CompilerServices.Extension>
- Public Sub FromPem(ByVal rsa As RSA, pemString As String)
- Const FLAG_PUBLIC As String = "-----BEGIN PUBLIC KEY-----"
- Const FLAG_PRIVATE As String = "-----BEGIN PRIVATE KEY-----"
- Dim content As String = pemString
- If pemString.StartsWith(FLAG_PUBLIC) Then
- content = content.Replace(FLAG_PUBLIC, "").Replace("-----END PUBLIC KEY-----", "").Replace(vbCrLf, "")
- Dim publicKeyParam As RsaKeyParameters = PublicKeyFactory.CreateKey(Convert.FromBase64String(content))
- Dim xml As String = String.Format("<RSAKeyValue><Modulus>{0}</Modulus><Exponent>{1}</Exponent></RSAKeyValue>",
- Convert.ToBase64String(publicKeyParam.Modulus.ToByteArrayUnsigned),
- Convert.ToBase64String(publicKeyParam.Exponent.ToByteArrayUnsigned))
- rsa.FromXml(xml)
- ElseIf pemString.StartsWith(FLAG_PRIVATE) Then
- content = content.Replace(FLAG_PRIVATE, "").Replace("-----END PRIVATE KEY-----", "").Replace(vbCrLf, "")
- Dim privateKeyParam As RsaPrivateCrtKeyParameters = PrivateKeyFactory.CreateKey(Convert.FromBase64String(content))
- Dim parameters As New RSAParameters() With
- {
- .Modulus = privateKeyParam.Modulus.ToByteArrayUnsigned(),
- .Exponent = privateKeyParam.PublicExponent.ToByteArrayUnsigned(),
- .P = privateKeyParam.P.ToByteArrayUnsigned(),
- .Q = privateKeyParam.Q.ToByteArrayUnsigned(),
- .DP = privateKeyParam.DP.ToByteArrayUnsigned(),
- .DQ = privateKeyParam.DQ.ToByteArrayUnsigned(),
- .InverseQ = privateKeyParam.QInv.ToByteArrayUnsigned(),
- .D = privateKeyParam.Exponent.ToByteArrayUnsigned()
- }
- rsa.ImportParameters(parameters)
- Else
- Throw New ArgumentException("pemString is not validate")
- End If
- End Sub
- <System.Runtime.CompilerServices.Extension>
- Public Function ToPem(ByVal rsa As RSA, ByVal includePrivateParameters As Boolean) As String
- Dim ret As String = String.Empty
- If includePrivateParameters Then
- Return exportPrivateKey(rsa)
- Else
- Return exportPublicKey(rsa)
- End If
- End Function
- ''' <summary>
- ''' 输出PEM格式公钥
- ''' </summary>
- ''' <param name="rsa"></param>
- ''' <returns></returns>
- Private Function exportPublicKey(ByVal rsa As RSA) As String
- Dim outputStream As TextWriter = New StringWriter()
- Dim parameters = rsa.ExportParameters(False)
- Using stream = New MemoryStream()
- Dim writer = New BinaryWriter(stream)
- writer.Write(CByte(&H30)) ' SEQUENCE
- Using innerStream = New MemoryStream()
- Dim innerWriter = New BinaryWriter(innerStream)
- innerWriter.Write(CByte(&H30)) ' SEQUENCE
- encodeLength(innerWriter, )
- innerWriter.Write(CByte(&H6)) ' OBJECT IDENTIFIER
- Dim rsaEncryptionOid = New Byte() {&H2A, &H86, &H48, &H86, &HF7, &HD, &H1, &H1, &H1}
- encodeLength(innerWriter, rsaEncryptionOid.Length)
- innerWriter.Write(rsaEncryptionOid)
- innerWriter.Write(CByte(&H5)) ' NULL
- encodeLength(innerWriter, )
- innerWriter.Write(CByte(&H3)) ' BIT STRING
- Using bitStringStream = New MemoryStream()
- Dim bitStringWriter = New BinaryWriter(bitStringStream)
- bitStringWriter.Write(CByte(&H0)) ' # of unused bits
- bitStringWriter.Write(CByte(&H30)) ' SEQUENCE
- Using paramsStream = New MemoryStream()
- Dim paramsWriter = New BinaryWriter(paramsStream)
- encodeIntegerBigEndian(paramsWriter, parameters.Modulus) ' Modulus
- encodeIntegerBigEndian(paramsWriter, parameters.Exponent) ' Exponent
- Dim paramsLength = CInt(paramsStream.Length)
- encodeLength(bitStringWriter, paramsLength)
- bitStringWriter.Write(paramsStream.GetBuffer(), , paramsLength)
- End Using
- Dim bitStringLength = CInt(bitStringStream.Length)
- encodeLength(innerWriter, bitStringLength)
- innerWriter.Write(bitStringStream.GetBuffer(), , bitStringLength)
- End Using
- Dim length = CInt(innerStream.Length)
- encodeLength(writer, length)
- writer.Write(innerStream.GetBuffer(), , length)
- End Using
- Dim base64 = Convert.ToBase64String(stream.GetBuffer(), , CInt(stream.Length)).ToCharArray()
- outputStream.WriteLine("-----BEGIN PUBLIC KEY-----")
- For i = To base64.Length - Step
- outputStream.WriteLine(base64, i, Math.Min(, base64.Length - i))
- Next i
- outputStream.WriteLine("-----END PUBLIC KEY-----")
- End Using
- Return outputStream.ToString
- End Function
- ''' <summary>
- ''' 输出PEM格式私钥
- ''' </summary>
- ''' <param name="rsa"></param>
- Private Function exportPrivateKey(ByVal rsa As RSA) As String
- 'If csp.PublicOnly Then
- ' Throw New ArgumentException("CSP does not contain a private key", "csp")
- 'End If
- Dim outputStream As TextWriter = New StringWriter()
- Dim parameters = rsa.ExportParameters(True)
- If parameters.D Is Nothing Then
- Throw New ArgumentException("object does not contain a private key", "csp")
- End If
- Using stream = New MemoryStream()
- Dim writer = New BinaryWriter(stream)
- writer.Write(CByte(&H30)) ' SEQUENCE
- Using innerStream = New MemoryStream()
- Dim innerWriter = New BinaryWriter(innerStream)
- encodeIntegerBigEndian(innerWriter, New Byte() {&H0}) ' Version
- encodeIntegerBigEndian(innerWriter, parameters.Modulus)
- encodeIntegerBigEndian(innerWriter, parameters.Exponent)
- encodeIntegerBigEndian(innerWriter, parameters.D)
- encodeIntegerBigEndian(innerWriter, parameters.P)
- encodeIntegerBigEndian(innerWriter, parameters.Q)
- encodeIntegerBigEndian(innerWriter, parameters.DP)
- encodeIntegerBigEndian(innerWriter, parameters.DQ)
- encodeIntegerBigEndian(innerWriter, parameters.InverseQ)
- Dim length = CInt(innerStream.Length)
- encodeLength(writer, length)
- writer.Write(innerStream.GetBuffer(), , length)
- End Using
- Dim base64 = Convert.ToBase64String(stream.GetBuffer(), , CInt(stream.Length)).ToCharArray()
- outputStream.WriteLine("-----BEGIN RSA PRIVATE KEY-----")
- ' Output as Base64 with lines chopped at 64 characters
- For i = To base64.Length - Step
- outputStream.WriteLine(base64, i, Math.Min(, base64.Length - i))
- Next i
- outputStream.WriteLine("-----END RSA PRIVATE KEY-----")
- End Using
- Return outputStream.ToString
- End Function
- Private Sub encodeLength(ByVal stream As BinaryWriter, ByVal length As Integer)
- If length < Then
- Throw New ArgumentOutOfRangeException("length", "Length must be non-negative")
- End If
- If length < &H80 Then
- ' Short form
- stream.Write(CByte(length))
- Else
- ' Long form
- Dim temp = length
- Dim bytesRequired =
- Do While temp >
- temp >>=
- bytesRequired +=
- Loop
- stream.Write(CByte(bytesRequired Or &H80))
- For i = bytesRequired - To Step -
- stream.Write(CByte(length >> ( * i) And &HFF))
- Next i
- End If
- End Sub
- Private Sub encodeIntegerBigEndian(ByVal stream As BinaryWriter, ByVal value() As Byte, Optional ByVal forceUnsigned As Boolean = True)
- stream.Write(CByte(&H2)) ' INTEGER
- Dim prefixZeros =
- For i = To value.Length -
- If value(i) <> Then
- Exit For
- End If
- prefixZeros +=
- Next i
- If value.Length - prefixZeros = Then
- encodeLength(stream, )
- stream.Write(CByte())
- Else
- If forceUnsigned AndAlso value(prefixZeros) > &H7F Then
- ' Add a prefix zero to force unsigned if the MSB is 1
- encodeLength(stream, value.Length - prefixZeros + )
- stream.Write(CByte())
- Else
- encodeLength(stream, value.Length - prefixZeros)
- End If
- For i = prefixZeros To value.Length -
- stream.Write(value(i))
- Next i
- End If
- End Sub
- End Module
- Friend Module DotNetCoreUtilities
- ''' <summary>
- ''' 返回 RSA 对象的 密钥对参数对象
- ''' </summary>
- ''' <param name="provider"></param>
- ''' <returns>
- ''' 用私钥初始化的 RSA 对象 - 返回有效的公钥和私钥密钥对
- ''' 用公钥初始化的 RSA 对象 - 返回 有效的公钥 和 无效的私钥组成的密钥对
- ''' </returns>
- Public Function GetKeyPair(ByVal provider As RSA) As AsymmetricCipherKeyPair
- Dim p As RSAParameters
- Dim rkpPrivate As RsaKeyParameters
- Try
- p = provider.ExportParameters(True)
- rkpPrivate = New RsaKeyParameters(True, New BigInteger(, p.Modulus), New BigInteger(p.D)) '//PrivateKey 实际使用
- Catch ex As Exception
- p = provider.ExportParameters(False)
- rkpPrivate = New RsaKeyParameters(True, BigInteger.One, BigInteger.One) '//PrivateKey 实际不使用
- End Try
- Dim rpkPublic As New RsaKeyParameters(False, New BigInteger(, p.Modulus), New BigInteger(p.Exponent))
- Dim keyPair As New AsymmetricCipherKeyPair(rpkPublic, rkpPrivate)
- Return keyPair
- End Function
- ''' <summary>
- ''' 通过 PEM 格式的私钥返回 密钥对参数对象
- ''' </summary>
- ''' <param name="privateKey">PEM 格式的私钥</param>
- ''' <returns></returns>
- Public Function GetKeyPair(ByVal privateKey As String) As AsymmetricCipherKeyPair
- Dim keyPair As AsymmetricCipherKeyPair
- Using StringReader As New StringReader(privateKey)
- Dim pemReader = New PemReader(StringReader)
- keyPair = CType(pemReader.ReadObject, AsymmetricCipherKeyPair)
- End Using
- Return keyPair
- End Function
- ''' <summary>
- ''' 通过 PEM 格式的公钥返回 密钥参数对象
- ''' </summary>
- ''' <param name="publicKey">PEM 格式的公钥</param>
- ''' <returns></returns>
- Public Function GetKeyParmeter(ByVal publicKey As String) As AsymmetricKeyParameter
- Dim ret As AsymmetricKeyParameter
- Using StringReader As New StringReader(publicKey)
- Dim pemReader = New PemReader(StringReader)
- ret = CType(pemReader.ReadObject, AsymmetricKeyParameter)
- End Using
- Return ret
- End Function
- End Module
最后是调用代码示例:
- Dim ciphertext As String = RSAHelper.PublicKeyEncryptEx(RSAHelper.PublicKey, plaintext)
- Console.WriteLine("===== ciphertext.Length={0}, PublicKeyEncypt Result:", ciphertext.Length)
- Console.WriteLine(ciphertext)
- Dim newData As String = RSAHelper.PrivateKeyDecryptEx(RSAHelper.PrivateKey, ciphertext)
- Console.WriteLine("===== PrivateKeyDecrypt Result:")
- Console.WriteLine(newData.Equals(plaintext))
- Console.WriteLine("==============================================")
- Console.WriteLine()
- ciphertext = RSAHelper.PrivateKeyEncryptEx(RSAHelper.PrivateKey, plaintext)
- Console.WriteLine("ciphertext.Length={0}, PrivateKeyEncypt Result:", ciphertext.Length)
- Console.WriteLine(ciphertext)
- newData = RSAHelper.PublicKeyDecryptEx(RSAHelper.PublicKey, ciphertext)
- Console.WriteLine("===== PublicKeyDecrypt {0}", newData.Equals(plaintext))
PS:如果需要与Java交换密钥文件,可参考 https://www.cnblogs.com/wuweimin/p/7839335.html
参考文档:
https://blog.csdn.net/u010792238/article/details/79471406
https://www.cnblogs.com/taiyonghai/p/6150353.html
https://stackoverflow.com/questions/23734792/c-sharp-export-private-public-rsa-key-from-rsacryptoserviceprovider-to-pem-strin/25591659#25591659
可用的 .net core 支持 RSA 私钥加密工具类的更多相关文章
- Delphi RSA加解密【 (RSA公钥加密,私钥解密)、(RSA私钥加密,公钥解密)、MD5加密、SHA加密】
作者QQ:(648437169) 点击下载➨delphi RSA加解密 [Delphi RSA加解密]支持 (RSA公钥加密,私钥解密).(RSA私钥加密,公钥解密).MD5加密.SHA1加密.SHA ...
- 求求你们不要再用 RSA 私钥加密公钥解密了,这非常不安全!
最近经常在网上看到有人说巨硬的 CNG(Cryptography Next Generation 即下一代加密技术) 只提供 RSA 公钥加密私钥解密,没有提供 RSA 私钥加密公钥解密,他们要自己封 ...
- java 加密工具类(MD5、RSA、AES等加密方式)
1.加密工具类encryption MD5加密 import org.apache.commons.codec.digest.DigestUtils; /** * MD5加密组件 * * @autho ...
- RSA加解密工具类RSAUtils.java,实现公钥加密私钥解密和私钥解密公钥解密
package com.geostar.gfstack.cas.util; import org.apache.commons.codec.binary.Base64; import javax.cr ...
- 关于RSA加密算法的工具类
关于RSA加密算法的工具类 最近在捣鼓SSO(单点登录),就是一个在应用(系统)登录之后,当切换其他应用(系统)的时候,可以省去登录,提高用户的使用的便捷.(具体有时间在写) 期间涉及的安全问题,发送 ...
- java MD5Utils 加密工具类
package com.sicdt.library.core.utils; import java.io.File; import java.io.FileInputStream; import ja ...
- App开发流程之加密工具类
科技优家 2016-09-08 18:10 从这篇记录开始,记录的都算是干货了,都是一些编程日常的积累. 我建议先将基础的工具加入项目,后续的开发效率会呈指数增长.如果在专注功能开发过程中,才发现缺少 ...
- 加密工具类 - CryptoUtils.java
加密工具类,包含MD5,BASE64,SHA,CRC32的加密与解密方法. 源码如下:(点击下载 - CryptoUtils.java.commons-io-2.4.jar.commons-code ...
- android开发MD5加密工具类(一)
MD5加密工具类整理: package com.gzcivil.utils; import java.io.UnsupportedEncodingException; import java.secu ...
随机推荐
- python 的第一个界面程序(PyQt5)
这里用到了python的一个第三qt库PyQt5,API与qt几乎完全一样(科学严谨下...) from PyQt5.QtWidgets import QApplication, QMainWindo ...
- PAT Advanced 1111 Online Map (30) [Dijkstra算法 + DFS]
题目 Input our current position and a destination, an online map can recommend several paths. Now your ...
- 常用sql语句(mysql测试)
DB数据库,DatabaseDBMS数据库管理系统,DatabaMemanagmentSystemSQL结构化查询语言,structure Query Language 开启服务net start m ...
- JS-语句二
for循环的4个要素: 1.初始值 2.条件判断 3.状态改变 4.循环体 for循环的写法: for(var i=0;i>10;i++) ...
- 期末项目之 Json文件
Github上的json文件: https://raw.githubusercontent.com/color-me/first/master/b
- (转)jpbc的基本函数介绍
双线性群简介 质数阶双线性群(Prime-Order Bilinear Groups) 质数双线性群可以由五元组(p,G1,G2,GT,e)来描述.五元组中p是一个与给定安全常数λ相关的大质数,G1, ...
- GBDT入门
GBDT(MART)迭代决策树入门教程 GBDT(Gradient Boosting Decision Tree) 又叫 MART(Multiple Additive Regression Tree) ...
- 201771010123汪慧和《面向对象程序设计JAVA》第七周实验总结
一.理论部分 1.继承 如果两个类存在继承关系,则子类会自动继承父类的方法和变量,在子类中可以调用父类的方法和变量,如果想要在子类里面做一系列事情,应该放在父类无参构造器里面,在java中,只允许单继 ...
- css块级元素
<CSS权威指南>中文字显示:任何不是块级元素的可见元素都是内联元素.其表现的特性是“行布局”形式,这里的“行布局”的意思就是说其表现形式始终以行进行显示.比如,我们设定一个内联元素bor ...
- 程序Dog的大梦想
一.我是程序狗 "怎么又是任宏啊,每天都起这么早,要命啊--" "人家任宏可是要成为学霸的男人,咱们这些凡夫俗子啊,理解不了这么伟大的理想--"----微电影& ...