感谢晓晨的C#版《.NET Core 使用RSA算法 加密/解密/签名/验证签名》
为了便于大家学习,翻译成了VB版,并测试通过
原文地址:https://cloud.tencent.com/developer/article/1151210
1 Imports System.IO 2 Imports System.Security.Cryptography 3 Imports System.Text 4 5 ''' <summary> 6 ''' SA加解密 使用OpenSSL的公钥加密/私钥解密 7 ''' https://cloud.tencent.com/developer/article/1151210 8 ''' </summary> 9 Public Class Class_RSAHelper 10 Private ReadOnly _privateKeyRsaProvider As RSA 11 Private ReadOnly _publicKeyRsaProvider As RSA 12 Private ReadOnly _hashAlgorithmName As HashAlgorithmName 13 Private ReadOnly _encoding As Encoding 14 15 ''' <summary> 16 ''' 17 ''' </summary> 18 ''' <param name="rsaType">加密算法类型 RSA SHA1;RSA2 SHA256 密钥长度至少为2048</param> 19 ''' <param name="encoding">编码类型</param> 20 ''' <param name="privateKey">私钥</param> 21 ''' <param name="publicKey">公钥</param> 22 Public Sub New(rsaType As RSAType, 23 encoding As Encoding, 24 privateKey As String, 25 publicKey As String 26 ) 27 If rsaType = RSAType.RSA Then 28 _hashAlgorithmName = HashAlgorithmName.SHA1 29 Else 30 _hashAlgorithmName = HashAlgorithmName.SHA256 31 End If 32 33 _encoding = encoding 34 35 If Not String.IsNullOrEmpty(privateKey) Then 36 _privateKeyRsaProvider = CreateRsaProviderFromPrivateKey(privateKey) 37 End If 38 If Not String.IsNullOrEmpty(publicKey) Then 39 _publicKeyRsaProvider = CreateRsaProviderFromPublicKey(publicKey) 40 End If 41 End Sub 42 43 44 45 ''' <summary> 46 ''' 使用私钥签名 47 ''' </summary> 48 ''' <param name="data">原始数据</param> 49 ''' <returns></returns> 50 Public Function Sign(data As String) As String 51 Dim dataBytes As Byte() = _encoding.GetBytes(data) 52 Dim signatureBytes = _privateKeyRsaProvider.SignData(dataBytes, _hashAlgorithmName, RSASignaturePadding.Pkcs1) 53 Return Convert.ToBase64String(signatureBytes) 54 End Function 55 56 57 58 59 60 ''' <summary> 61 ''' 使用公钥验证签名 62 ''' </summary> 63 ''' <param name="data">原始数据</param> 64 ''' <param name="sign">签名</param> 65 ''' <returns></returns> 66 Public Function Verify(data As String, sign As String) As Boolean 67 68 Dim dataBytes As Byte() = _encoding.GetBytes(data) 69 Dim signBytes As Byte() = Convert.FromBase64String(sign) 70 71 Return _publicKeyRsaProvider.VerifyData(dataBytes, signBytes, _hashAlgorithmName, RSASignaturePadding.Pkcs1) 72 End Function 73 74 75 ''' <summary> 76 ''' 解密 77 ''' </summary> 78 ''' <param name="String"></param> 79 ''' <returns></returns> 80 Public Function Decrypt(cipherText As String) As String 81 82 If IsNothing(_privateKeyRsaProvider) Then 83 Throw New Exception("_privateKeyRsaProvider is null") 84 End If 85 Return Encoding.UTF8.GetString(_privateKeyRsaProvider.Decrypt(Convert.FromBase64String(cipherText), RSAEncryptionPadding.Pkcs1)) 86 End Function 87 88 89 ''' <summary> 90 ''' 加密 91 ''' </summary> 92 ''' <param name="String"></param> 93 ''' <returns></returns> 94 Public Function Encrypt(text As String) As String 95 If IsNothing(_publicKeyRsaProvider) Then 96 Throw New Exception("_publicKeyRsaProvider is null") 97 End If 98 Return Convert.ToBase64String(_publicKeyRsaProvider.Encrypt(Encoding.UTF8.GetBytes(text), RSAEncryptionPadding.Pkcs1)) 99 End Function 100 101 102 103 104 105 ''' <summary> 106 ''' 使用私钥创建RSA实例 107 ''' </summary> 108 ''' <param name="String"></param> 109 ''' <returns></returns> 110 Public Function CreateRsaProviderFromPrivateKey(privateKey As String) As RSA 111 112 Dim privateKeyBits = Convert.FromBase64String(privateKey) 113 Dim RSA = System.Security.Cryptography.RSA.Create() 114 Dim RSAParameters = New RSAParameters() 115 116 Using binr As BinaryReader = New BinaryReader(New MemoryStream(privateKeyBits)) 117 Dim bt As Byte = 0 118 Dim twobytes As UShort = 0 119 twobytes = binr.ReadUInt16() 120 121 If twobytes = &H8130 Then 122 binr.ReadByte() 123 ElseIf twobytes = &H8230 Then 124 binr.ReadInt16() 125 Else 126 Throw New Exception("Unexpected value read binr.ReadUInt16()") 127 End If 128 129 twobytes = binr.ReadUInt16() 130 If twobytes <> &H102 Then 131 Throw New Exception("Unexpected version") 132 End If 133 134 bt = binr.ReadByte() 135 If bt <> &H0 Then 136 Throw New Exception("Unexpected value read binr.ReadByte()") 137 End If 138 139 RSAParameters.Modulus = binr.ReadBytes(GetIntegerSize(binr)) 140 RSAParameters.Exponent = binr.ReadBytes(GetIntegerSize(binr)) 141 RSAParameters.D = binr.ReadBytes(GetIntegerSize(binr)) 142 RSAParameters.P = binr.ReadBytes(GetIntegerSize(binr)) 143 RSAParameters.Q = binr.ReadBytes(GetIntegerSize(binr)) 144 RSAParameters.DP = binr.ReadBytes(GetIntegerSize(binr)) 145 RSAParameters.DQ = binr.ReadBytes(GetIntegerSize(binr)) 146 RSAParameters.InverseQ = binr.ReadBytes(GetIntegerSize(binr)) 147 End Using 148 149 RSA.ImportParameters(RSAParameters) 150 Return RSA 151 End Function 152 153 154 155 ''' <summary> 156 ''' 使用公钥创建RSA实例 157 ''' </summary> 158 ''' <param name="publicKeyString"></param> 159 ''' <returns></returns> 160 Public Function CreateRsaProviderFromPublicKey(publicKeyString As String) As RSA 161 162 ' encoded OID sequence for PKCS #1 rsaEncryption szOID_RSA_RSA = "1.2.840.113549.1.1.1" 163 Dim seqOid As Byte() = {&H30, &HD, &H6, &H9, &H2A, &H86, &H48, &H86, &HF7, &HD, &H1, &H1, &H1, &H5, &H0} 164 Dim seq(15) As Byte 165 166 Dim x509Key = Convert.FromBase64String(publicKeyString) 167 168 ' --------- Set up stream to read the asn.1 encoded SubjectPublicKeyInfo blob ------ 169 Using mem As MemoryStream = New MemoryStream(x509Key) 170 Using binr As BinaryReader = New BinaryReader(mem) 'wrap Memory Stream with BinaryReader for easy reading 171 Dim bt As Byte = 0 172 Dim twobytes As UShort = 0 173 174 twobytes = binr.ReadUInt16() 175 If twobytes = &H8130 Then ' Data Then read As little endian order (actual data order For Sequence Is 30 81) 176 binr.ReadByte() 'advance 1 Byte 177 ElseIf twobytes = &H8230 Then 178 binr.ReadInt16() 'advance 2 bytes 179 Else 180 Return Nothing 181 End If 182 183 seq = binr.ReadBytes(15) 'read the Sequence OID 184 If CompareBytearrays(seq, seqOid) = False Then ' make Then sure Sequence For OID Is correct 185 Return Nothing 186 End If 187 188 189 twobytes = binr.ReadUInt16() 190 If twobytes = &H8103 Then ' Data Then read As little endian order (actual data order For Bit String Is 03 81) 191 binr.ReadByte() 'advance 1 Byte 192 ElseIf twobytes = &H8203 Then 193 binr.ReadInt16() 'advance 2 bytes 194 Else 195 Return Nothing 196 End If 197 198 199 bt = binr.ReadByte() 200 If bt <> &H0 Then ' expect Then null Byte Next 201 Return Nothing 202 End If 203 204 twobytes = binr.ReadUInt16() 205 If twobytes = &H8130 Then ' Data Then read As little endian order (actual data order For Sequence Is 30 81) 206 binr.ReadByte() 'advance 1 Byte 207 ElseIf twobytes = &H8230 Then 208 binr.ReadInt16() 'advance 2 bytes 209 Else 210 Return Nothing 211 End If 212 213 twobytes = binr.ReadUInt16() 214 Dim lowbyte As Byte = &H0 215 Dim highbyte As Byte = &H0 216 217 If twobytes = &H8102 Then ' Data Then read As little endian order (actual data order For Integer Is 02 81) 218 lowbyte = binr.ReadByte() ' read Next bytes which Is bytes In modulus 219 ElseIf twobytes = &H8202 Then 220 highbyte = binr.ReadByte() 'advance 2 bytes 221 lowbyte = binr.ReadByte() 222 Else 223 Return Nothing 224 End If 225 226 Dim modint As Byte() = {lowbyte, highbyte, &H0, &H0} 'reverse Byte order since asn.1 key uses big endian order 227 Dim modsize As Integer = BitConverter.ToInt32(modint, 0) 228 229 Dim firstbyte As Integer = binr.PeekChar() 230 If firstbyte = &H0 Then 231 'if first byte (highest order) of modulus Is zero, don't include it 232 binr.ReadByte() 'skip this null Byte 233 modsize -= 1 'reduce modulus buffer size by 1 234 End If 235 236 Dim modulus As Byte() = binr.ReadBytes(modsize) 'read the modulus bytes 237 If binr.ReadByte() <> &H2 Then ' expect Then an Integer For the exponent data 238 Return Nothing 239 End If 240 241 Dim expbytes As Integer = binr.ReadByte() ' should only need one Byte For actual exponent data (For all useful values) 242 Dim exponent As Byte() = binr.ReadBytes(expbytes) 243 244 ' ------- create RSACryptoServiceProvider instance And initialize with public key ----- 245 Dim RSA = System.Security.Cryptography.RSA.Create() 246 Dim rsaKeyInfo As RSAParameters = New RSAParameters With { 247 .Modulus = modulus, 248 .Exponent = exponent 249 } 250 RSA.ImportParameters(rsaKeyInfo) 251 252 Return RSA 253 End Using 254 255 End Using 256 End Function 257 258 259 260 261 262 ''' <summary> 263 ''' 导入密钥算法 264 ''' </summary> 265 ''' <param name="BinaryReader"></param> 266 ''' <returns></returns> 267 Private Function GetIntegerSize(binr As BinaryReader) As Integer 268 269 Dim bt As Byte = 0 270 Dim count As Integer = 0 271 bt = binr.ReadByte() 272 If bt <> &H2 Then 273 Return 0 274 End If 275 276 bt = binr.ReadByte() 277 278 If bt = &H81 Then 279 count = binr.ReadByte() 280 Else 281 If bt = &H82 Then 282 Dim highbyte = binr.ReadByte() 283 Dim lowbyte = binr.ReadByte() 284 Dim modint As Byte() = {lowbyte, highbyte, &H0, &H0} 285 count = BitConverter.ToInt32(modint, 0) 286 Else 287 count = bt 288 End If 289 End If 290 291 While binr.ReadByte() = &H0 292 count -= 1 293 End While 294 binr.BaseStream.Seek(-1, SeekOrigin.Current) 295 Return count 296 End Function 297 298 299 Private Function CompareBytearrays(a As Byte(), b As Byte()) As Boolean 300 301 If (a.Length <> b.Length) Then 302 Return False 303 End If 304 305 Dim i As Integer = 0 306 For Each c As Byte In a 307 If c <> b(i) Then 308 Return False 309 End If 310 i += 1 311 Next 312 313 Return True 314 End Function 315 316 317 318 ''' <summary> 319 ''' RSA算法类型 320 ''' </summary> 321 Public Enum RSAType 322 323 ''' <summary> 324 ''' SHA1 325 ''' </summary> 326 RSA = 0 327 ''' <summary> 328 ''' RSA2 密钥长度至少为2048 329 ''' SHA256 330 ''' </summary> 331 RSA2 332 End Enum 333 End Class