.NET Core 使用RSA算法 加密/解密/签名/验证签名 【VB.net翻译版】
感谢晓晨的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 '''6 ''' SA加解密 使用OpenSSL的公钥加密/私钥解密 7 ''' https://cloud.tencent.com/developer/article/1151210 8 ''' 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 ''' 16 ''' 17 ''' 18 ''' 加密算法类型 RSA SHA1;RSA2 SHA256 密钥长度至少为2048 19 ''' 编码类型 20 ''' 私钥 21 ''' 公钥 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 ''' 46 ''' 使用私钥签名 47 ''' 48 ''' 原始数据 49 ''' 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 ''' 61 ''' 使用公钥验证签名 62 ''' 63 ''' 原始数据 64 ''' 签名 65 ''' 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 ''' 76 ''' 解密 77 ''' 78 ''' 79 ''' 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 ''' 90 ''' 加密 91 ''' 92 ''' 93 ''' 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 ''' 106 ''' 使用私钥创建RSA实例 107 ''' 108 ''' 109 ''' 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 ''' 156 ''' 使用公钥创建RSA实例 157 ''' 158 ''' 159 ''' 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 ''' 263 ''' 导入密钥算法 264 ''' 265 ''' 266 ''' 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 ''' 319 ''' RSA算法类型 320 ''' 321 Public Enum RSAType 322 323 ''' 324 ''' SHA1 325 ''' 326 RSA = 0 327 ''' 328 ''' RSA2 密钥长度至少为2048 329 ''' SHA256 330 ''' 331 RSA2 332 End Enum 333 End Class