技术 - Visual Basic - 非对称加密算法(包含证书)加密解密签名验签

31
09 Mar.

非对称加密算法(包含证书)加密解密签名验签

最后更新: 2009/03/31  |  评论: 0  |  关键词: 非对称加密  加密  解密  签名  算法  验签  证书  

什么是对称加密和非对称加密?

  • 对称加密是指:有一个密钥,加密用它来加密,解密也需要用到它。因为加密解密都是用同一个密钥所以叫对称加密。
  • 非对称加密是指:就是有 2 个密钥,一个是公钥,一个是私钥。私钥是自己的,不能随便给人,公钥随便给,无所谓。一般是别人用你的公钥加密,然后把密文给你,你用你的私钥解密,这样一样加密和解密不是同一个密钥,所以叫非对称。

 

对称和非对称的优劣?

  • 对称加密有一个坏处只要拥有密钥的人都可以解密。
  • 非对称的好处是假如没有私钥,别人是无法解密的,就算加密的那个人他把数据加密了他也无法解密,加密者把密文和公钥随便给那个人都无法解密。

 

什么是数字签名?

  • 数字签名是指:用一段密码与原文进行加密,检测原文有没有被 篡改。意义就是这些数据与原文数据比对是否修改过,这个解释有点麻烦,一般是用自己的私钥对数据进行签名,然后用公钥去验证这个数据是否修改过

【本文代码还待验证,请待验证后再参考】

1、用 RSACryptoServiceProvider 加密解密

  1. '要加密的数据  
  2. Dim messageBytes As Byte() = Text.Encoding.UTF8.GetBytes("激情燃烧的木炭[http://www.woodcoal.cn/]")  
  3.  
  4. '1. 产生公匙和私匙,两个数据都要保存  
  5. Dim oRsa As New Security.Cryptography.RSACryptoServiceProvider  
  6. Dim privateKey As String = oRsa.ToXmlString(True)  
  7. Dim publicKey As String = oRsa.ToXmlString(False)  
  8.  
  9. '2. 用公匙加密数据  
  10. Dim oRsaEncode As New Security.Cryptography.RSACryptoServiceProvider  
  11. '导入公匙  
  12. oRsaEncode.FromXmlString(publicKey)  
  13. '输出加密后的数据  
  14. Dim resultByte As Byte() = oRsaEncode.Encrypt(messageBytes, False)  
  15.  
  16. '3. 用私匙解密数据  
  17. Dim oRsaDecode As New Security.Cryptography.RSACryptoServiceProvider  
  18. '导入私匙  
  19. oRsaDecode.FromXmlString(privateKey)  
  20. '输出解密后的数据  
  21. messageBytes = oRsaDecode.Decrypt(resultByte, False)  
  22.  
  23. '结果  
  24. Return Text.Encoding.UTF8.GetString(messageBytes) 

 

2、用 RSACryptoServiceProvider 签名验签

  1. '要加密的数据  
  2. Dim messageBytes As Byte() = Text.Encoding.UTF8.GetBytes("激情燃烧的木炭[http://www.woodcoal.cn/]")  
  3.  
  4. '1. 产生公匙和私匙,两个数据都要保存  
  5. Dim oRsa As New Security.Cryptography.RSACryptoServiceProvider  
  6. Dim privateKey As String = oRsa.ToXmlString(True)  
  7. Dim publicKey As String = oRsa.ToXmlString(False)  
  8.  
  9. '2. 用私钥匙签名数据  
  10. Dim oRsaEncode As New Security.Cryptography.RSACryptoServiceProvider  
  11. '导入私钥  
  12. oRsaEncode.FromXmlString(privateKey)  
  13. '输出签名后的数据  
  14. Dim resultByte As Byte() = oRsaEncode.SignData(messageBytes, "SHA1")  
  15.  
  16. '3. 用公钥验证数据  
  17. Dim oRsaDecode As New Security.Cryptography.RSACryptoServiceProvider  
  18. '导入公钥  
  19. oRsaDecode.FromXmlString(publicKey)  
  20. '输出验证后的结果,是否验证成功  
  21. Return oRsaDecode.VerifyData(resultByte, "SHA1", messageBytes) 

3、用证书进行签名

因为一般证书的私钥是不可以导出的,所以用第 2 种方法导入私钥的来进行签名行不通。

  1. '要加密的数据  
  2. Dim messageBytes As Byte() = Text.Encoding.UTF8.GetBytes("激情燃烧的木炭[http://www.woodcoal.cn/]")  
  3. Dim certificatePath As String = "E:\Certificate.P12" 
  4.  
  5. '导入证书  
  6. Dim x509 As New Security.Cryptography.X509Certificates.X509Certificate2(certificatePath, "Import Password")  
  7. Dim privateKey As Security.Cryptography.RSACryptoServiceProvider = x509.PrivateKey  
  8. Dim publicKey As String = x509.PublicKey.Key.ToXmlString(False)  
  9.  
  10. '对要签名的数据进行哈希  
  11. Dim sha1 As New Security.Cryptography.SHA1CryptoServiceProvider  
  12. Dim hashBytes As Byte() = sha1.ComputeHash(messageBytes)  
  13.  
  14. '签名对象  
  15. Dim signe As New Security.Cryptography.RSAPKCS1SignatureFormatter  
  16. '设置签名用到的私钥   
  17. signe.SetKey(privateKey)  
  18. '设置签名算法   
  19. signe.SetHashAlgorithm("SHA1")  
  20. '返回结果  
  21. Dim reslutBytes As Byte() = signe.CreateSignature(hashBytes)  
  22.  
  23.  
  24. '3. 用公钥验证数据,与第2方法相同  
  25. Dim oRsaDecode As New Security.Cryptography.RSACryptoServiceProvider  
  26. '导入公钥  
  27. oRsaDecode.FromXmlString(publicKey)  
  28. '输出验证后的结果,是否验证成功  
  29. Return oRsaDecode.VerifyData(resultByte, "SHA1", messageBytes) 

 

 4、用证书加密解密

  1. '要加密的数据  
  2. Dim messageBytes As Byte() = Text.Encoding.UTF8.GetBytes("激情燃烧的木炭[http://www.woodcoal.cn/]")  
  3. Dim certificatePath As String = "E:\Certificate.P12" 
  4.  
  5. '导入证书  
  6. Dim x509 As New Security.Cryptography.X509Certificates.X509Certificate2(certificatePath, "Import Password")  
  7. Dim privateKey As Security.Cryptography.RSACryptoServiceProvider = x509.PrivateKey  
  8. Dim publicKey As String = x509.PublicKey.Key.ToXmlString(False)  
  9.  
  10. '证书公钥加密  
  11. Dim oRsaEncode As New Security.Cryptography.RSACryptoServiceProvider  
  12. oRsaEncode.FromXmlString(publicKey)  
  13. Dim resultBytes As Byte() = oRsaEncode.Encrypt(messageBytes, False)  
  14.  
  15. '证书私钥解密   
  16. Dim oRsaDecode As Security.Cryptography.RSACryptoServiceProvider = DirectCast(privateKey, Security.Cryptography.RSACryptoServiceProvider)  
  17. messageBytes = oRsaDecode.Decrypt(resultBytes, False)  
  18.  
  19. '返回结果  
  20. Return Text.Encoding.UTF8.GetString(messageBytes) 

5、用证书对文件加密解密

因为文件可能特别大 所以需要用流和 Buffer 的方式,如果把文件全部读到 Byte() 里进行加密,当文件很大,比如 5G,那全部读到 Byte() 里崩溃掉

  1. ''' <summary>用证书加密文件</summary>  
  2. ''' <param name="certificatePath">证书路径</param>  
  3. ''' <param name="certificatePassword">证书导入密码</param>  
  4. ''' <param name="sourcePath">需要加密的文件路径</param>  
  5. ''' <param name="targetPath">加密后的文件路径</param>  
  6. ''' <remarks></remarks>  
  7. Public Sub Encrypt(ByVal certificatePath As StringByVal certificatePassword As StringByVal sourcePath As StringByVal targetPath As String)  
  8.     '导入证书  
  9.     Dim x509 As New Security.Cryptography.X509Certificates.X509Certificate2(certificatePath, certificatePassword)  
  10.     'Dim privateKey As Security.Cryptography.RSACryptoServiceProvider = x509.PrivateKey  
  11.     Dim publicKey As String = x509.PublicKey.Key.ToXmlString(False)  
  12.  
  13.     Dim oRsa As New Security.Cryptography.RSACryptoServiceProvider()  
  14.     oRsa.FromXmlString(publicKey)  
  15.     Dim sourceStream As New System.IO.FileStream(sourcePath, System.IO.FileMode.Open)  
  16.     Dim targetStream As New System.IO.FileStream(targetPath, System.IO.FileMode.OpenOrCreate)  
  17.  
  18.     Dim blockSize As Integer = 0  
  19.     If oRsa.KeySize = 1024 Then 
  20.         blockSize = 16  
  21.     Else 
  22.         blockSize = 8  
  23.     End If 
  24.  
  25.     Dim K As Integer = 1  
  26.     While K > 0  
  27.         Dim buffer As Byte() = New Byte(blockSize - 1) {}  
  28.  
  29.         K = sourceStream.Read(buffer, 0, buffer.Length)  
  30.         If K > 0 Then 
  31.             Dim buffer1 As Byte(), encryblock As Byte()  
  32.             If blockSize = K Then 
  33.                 encryblock = oRsa.Encrypt(buffer, False)  
  34.                 targetStream.Write(encryblock, 0, encryblock.Length)  
  35.             Else 
  36.                 buffer1 = New Byte(K - 1) {}  
  37.                 For i As Integer = 0 To K - 1  
  38.                     buffer1(i) = buffer(i)  
  39.                 Next 
  40.                 encryblock = oRsa.Encrypt(buffer1, False)  
  41.                 targetStream.Write(encryblock, 0, encryblock.Length)  
  42.             End If 
  43.         Else 
  44.             sourceStream.Close()  
  45.             targetStream.Close()  
  46.         End If 
  47.     End While 
  48. End Sub 
  49.  
  50. ''' <summary>用证书解密文件</summary>  
  51. ''' <param name="certificatePath">证书路径</param>  
  52. ''' <param name="certificatePassword">证书导入密码</param>  
  53. ''' <param name="sourcePath">需要解密的文件路径</param>  
  54. ''' <param name="targetPath">解密后的文件路径</param>  
  55. ''' <remarks></remarks>  
  56. Public Sub Decrypt(ByVal certificatePath As StringByVal certificatePassword As StringByVal sourcePath As StringByVal targetPath As String)  
  57.     '导入证书  
  58.     Dim x509 As New Security.Cryptography.X509Certificates.X509Certificate2(certificatePath, certificatePassword)  
  59.     Dim privateKey As Security.Cryptography.RSACryptoServiceProvider = x509.PrivateKey  
  60.     'Dim publicKey As String = x509.PublicKey.Key.ToXmlString(False)  
  61.  
  62.     Dim oRsa As Security.Cryptography.RSACryptoServiceProvider = DirectCast(privateKey, Security.Cryptography.RSACryptoServiceProvider)  
  63.     Dim sourceStream As New System.IO.FileStream(sourcePath, System.IO.FileMode.Open)  
  64.     Dim targetStream As New System.IO.FileStream(targetPath, System.IO.FileMode.OpenOrCreate)  
  65.  
  66.     Dim blockSize As Integer = oRsa.KeySize / 8  
  67.     Dim buffer1 As Byte(), encryblock As Byte()  
  68.  
  69.     Dim K As Integer = 1  
  70.     While K > 0  
  71.         Dim buffer As Byte() = New Byte(blockSize - 1) {}  
  72.         K = sourceStream.Read(Buffer, 0, Buffer.Length)  
  73.         If K > 0 Then 
  74.             If blockSize = K Then 
  75.                 encryblock = oRsa.Decrypt(buffer, False)  
  76.                 targetStream.Write(encryblock, 0, encryblock.Length)  
  77.             Else 
  78.                 buffer1 = New Byte(K - 1) {}  
  79.                 For i As Integer = 0 To K - 1  
  80.                     buffer1(i) = buffer(i)  
  81.                 Next 
  82.                 encryblock = oRsa.Decrypt(buffer1, False)  
  83.                 targetStream.Write(encryblock, 0, encryblock.Length)  
  84.             End If 
  85.         Else 
  86.             sourceStream.Close()  
  87.             targetStream.Close()  
  88.         End If 
  89.     End While 
  90. End Sub 

 

 6、用证书对文件进行签名验签

  1. Private Sub Form1_Load(ByVal sender As ObjectByVal e As EventArgs)   
  2.     x509 = New X509Certificate2(Path, "12345678")   
  3.     SignFile("1.txt""11.txt")   
  4.       
  5.     VerifyFile("1.txt""11.txt")   
  6. End Sub   
  7. Private Function VerifyFile(ByVal FileName As StringByVal SignedFileName As StringAs Boolean   
  8.       
  9.     Dim reslut As Boolean = True   
  10.       
  11.     Dim objread As New System.IO.StreamReader(FileName)   
  12.     Dim objreadSigned As New System.IO.StreamReader(SignedFileName)   
  13.       
  14.     Dim VeryRsa As New RSACryptoServiceProvider()   
  15.     VeryRsa.FromXmlString(x509.PublicKey.Key.ToXmlString(False))   
  16.       
  17.     Dim Inblocksize As Integer = 0   
  18.     Dim Signedblocksize As Integer = 0   
  19.     If VeryRsa.KeySize = 1024 Then   
  20.         Inblocksize = 16   
  21.     Else   
  22.         Inblocksize = 8   
  23.     End If   
  24.     Signedblocksize = VeryRsa.KeySize / 8   
  25.       
  26.     Dim Closed As Boolean = True   
  27.     Dim Buffer As Byte()   
  28.     '原文缓存区   
  29.     Dim InBuffer As Byte()   
  30.     '原文缓存区   
  31.     Dim Buffer1 As Byte()   
  32.     '签名文件缓存区   
  33.     While Closed   
  34.         Buffer = Nothing   
  35.         Buffer = New Byte(Inblocksize - 1) {}   
  36.         Dim k As Integer = objread.BaseStream.Read(Buffer, 0, Buffer.Length)   
  37.         If k > 0 Then   
  38.             If Inblocksize = k Then   
  39.                 '读出来的长度和缓存区一样大   
  40.                 Buffer1 = New Byte(Signedblocksize - 1) {}   
  41.                 objreadSigned.BaseStream.Read(Buffer1, 0, Buffer1.Length)   
  42.                 reslut = VeryRsa.VerifyData(Buffer, "SHA1", Buffer1)   
  43.                 If Not reslut Then   
  44.                     Closed = False   
  45.                 End If   
  46.             Else   
  47.                 '意思是Buffer没满,只有k个字节,k字节后面全是空所以不需要验签   
  48.                 InBuffer = New Byte(k - 1) {}   
  49.                 For i As Integer = 0 To k - 1   
  50.                     InBuffer(i) = Buffer(i)   
  51.                 Next   
  52.                 Buffer1 = New Byte(Signedblocksize - 1) {}   
  53.                 objreadSigned.BaseStream.Read(Buffer1, 0, Buffer1.Length)   
  54.                 reslut = VeryRsa.VerifyData(InBuffer, "SHA1", Buffer1)   
  55.                 If Not reslut Then   
  56.                     Closed = False   
  57.                 End If   
  58.             End If   
  59.         Else   
  60.             '这里的意思是原文已经读完毕了,并且已经和签名文件对应验签成功,那么   
  61.             '签名文件也必须读完毕了。   
  62.             If objreadSigned.BaseStream.Position <> objreadSigned.BaseStream.Length Then   
  63.                 reslut = False   
  64.             End If   
  65.             objreadSigned.Close()   
  66.             objread.Close()   
  67.             Closed = False   
  68.         End If   
  69.     End While   
  70.     Return reslut   
  71.       
  72.       
  73. End Function   
  74. Private Sub SignFile(ByVal InFileName As StringByVal OutFileName As String)   
  75.     Dim SignRsa As RSACryptoServiceProvider = DirectCast(x509.PrivateKey, RSACryptoServiceProvider)   
  76.       
  77.     Dim objread As New System.IO.StreamReader(InFileName)   
  78.     Dim objwrite As New System.IO.StreamWriter(OutFileName, False)   
  79.       
  80.     Dim blocksize As Integer = 0   
  81.     If SignRsa.KeySize = 1024 Then   
  82.         blocksize = 16   
  83.     Else   
  84.         blocksize = 8   
  85.     End If   
  86.       
  87.     Dim Closed As Boolean = True   
  88.     Dim Buffer As Byte() = New Byte(blocksize - 1) {}   
  89.     Dim buffer1 As Byte(), SignBytes As Byte()   
  90.     While Closed   
  91.         Dim k As Integer = objread.BaseStream.Read(Buffer, 0, Buffer.Length)   
  92.         If k > 0 Then   
  93.             If k = blocksize Then   
  94.                 SignBytes = SignRsa.SignData(Buffer, "SHA1")   
  95.                 objwrite.BaseStream.Write(SignBytes, 0, SignBytes.Length)   
  96.             Else   
  97.                 buffer1 = New Byte(k - 1) {}   
  98.                 For i As Integer = 0 To k - 1   
  99.                     buffer1(i) = Buffer(i)   
  100.                 Next   
  101.                 SignBytes = SignRsa.SignData(buffer1, "SHA1")   
  102.                 objwrite.BaseStream.Write(SignBytes, 0, SignBytes.Length)   
  103.             End If   
  104.         Else   
  105.             Closed = False   
  106.             objread.Close()   
  107.             objwrite.Close()   
  108.         End If   
  109.     End While   
  110.       
  111.       
  112. End Sub  

 

· 本文由 木炭 发布在《激情燃烧的木炭》 上,原文地址为:http://www.woodcoal.cn/technology/visual-basic/2009331-18230-499.html(转载请保留本信息、全文内容和链接)

发表评论

已经有 0 位朋友发表了对《非对称加密算法(包含证书)加密解密签名验签》的看法
 
登录名:  密码:   登录  注册
评论: 
User:
Contact:
验证码:  
  [Ctrl+Enter]

关于本文