31
09 Mar.
非对称加密算法(包含证书)加密解密签名验签
最后更新: 2009/03/31 | 评论: 0 | 关键词: 非对称加密 加密 解密 签名 算法 验签 证书
什么是对称加密和非对称加密?
- 对称加密是指:有一个密钥,加密用它来加密,解密也需要用到它。因为加密解密都是用同一个密钥所以叫对称加密。
- 非对称加密是指:就是有 2 个密钥,一个是公钥,一个是私钥。私钥是自己的,不能随便给人,公钥随便给,无所谓。一般是别人用你的公钥加密,然后把密文给你,你用你的私钥解密,这样一样加密和解密不是同一个密钥,所以叫非对称。
对称和非对称的优劣?
- 对称加密有一个坏处只要拥有密钥的人都可以解密。
- 非对称的好处是假如没有私钥,别人是无法解密的,就算加密的那个人他把数据加密了他也无法解密,加密者把密文和公钥随便给那个人都无法解密。
什么是数字签名?
- 数字签名是指:用一段密码与原文进行加密,检测原文有没有被 篡改。意义就是这些数据与原文数据比对是否修改过,这个解释有点麻烦,一般是用自己的私钥对数据进行签名,然后用公钥去验证这个数据是否修改过
【本文代码还待验证,请待验证后再参考】
1、用 RSACryptoServiceProvider 加密解密
- '要加密的数据
- Dim messageBytes As Byte() = Text.Encoding.UTF8.GetBytes("激情燃烧的木炭[http://www.woodcoal.cn/]")
- '1. 产生公匙和私匙,两个数据都要保存
- Dim oRsa As New Security.Cryptography.RSACryptoServiceProvider
- Dim privateKey As String = oRsa.ToXmlString(True)
- Dim publicKey As String = oRsa.ToXmlString(False)
- '2. 用公匙加密数据
- Dim oRsaEncode As New Security.Cryptography.RSACryptoServiceProvider
- '导入公匙
- oRsaEncode.FromXmlString(publicKey)
- '输出加密后的数据
- Dim resultByte As Byte() = oRsaEncode.Encrypt(messageBytes, False)
- '3. 用私匙解密数据
- Dim oRsaDecode As New Security.Cryptography.RSACryptoServiceProvider
- '导入私匙
- oRsaDecode.FromXmlString(privateKey)
- '输出解密后的数据
- messageBytes = oRsaDecode.Decrypt(resultByte, False)
- '结果
- Return Text.Encoding.UTF8.GetString(messageBytes)
2、用 RSACryptoServiceProvider 签名验签
- '要加密的数据
- Dim messageBytes As Byte() = Text.Encoding.UTF8.GetBytes("激情燃烧的木炭[http://www.woodcoal.cn/]")
- '1. 产生公匙和私匙,两个数据都要保存
- Dim oRsa As New Security.Cryptography.RSACryptoServiceProvider
- Dim privateKey As String = oRsa.ToXmlString(True)
- Dim publicKey As String = oRsa.ToXmlString(False)
- '2. 用私钥匙签名数据
- Dim oRsaEncode As New Security.Cryptography.RSACryptoServiceProvider
- '导入私钥
- oRsaEncode.FromXmlString(privateKey)
- '输出签名后的数据
- Dim resultByte As Byte() = oRsaEncode.SignData(messageBytes, "SHA1")
- '3. 用公钥验证数据
- Dim oRsaDecode As New Security.Cryptography.RSACryptoServiceProvider
- '导入公钥
- oRsaDecode.FromXmlString(publicKey)
- '输出验证后的结果,是否验证成功
- Return oRsaDecode.VerifyData(resultByte, "SHA1", messageBytes)
3、用证书进行签名
因为一般证书的私钥是不可以导出的,所以用第 2 种方法导入私钥的来进行签名行不通。
- '要加密的数据
- Dim messageBytes As Byte() = Text.Encoding.UTF8.GetBytes("激情燃烧的木炭[http://www.woodcoal.cn/]")
- Dim certificatePath As String = "E:\Certificate.P12"
- '导入证书
- Dim x509 As New Security.Cryptography.X509Certificates.X509Certificate2(certificatePath, "Import Password")
- Dim privateKey As Security.Cryptography.RSACryptoServiceProvider = x509.PrivateKey
- Dim publicKey As String = x509.PublicKey.Key.ToXmlString(False)
- '对要签名的数据进行哈希
- Dim sha1 As New Security.Cryptography.SHA1CryptoServiceProvider
- Dim hashBytes As Byte() = sha1.ComputeHash(messageBytes)
- '签名对象
- Dim signe As New Security.Cryptography.RSAPKCS1SignatureFormatter
- '设置签名用到的私钥
- signe.SetKey(privateKey)
- '设置签名算法
- signe.SetHashAlgorithm("SHA1")
- '返回结果
- Dim reslutBytes As Byte() = signe.CreateSignature(hashBytes)
- '3. 用公钥验证数据,与第2方法相同
- Dim oRsaDecode As New Security.Cryptography.RSACryptoServiceProvider
- '导入公钥
- oRsaDecode.FromXmlString(publicKey)
- '输出验证后的结果,是否验证成功
- Return oRsaDecode.VerifyData(resultByte, "SHA1", messageBytes)
4、用证书加密解密
- '要加密的数据
- Dim messageBytes As Byte() = Text.Encoding.UTF8.GetBytes("激情燃烧的木炭[http://www.woodcoal.cn/]")
- Dim certificatePath As String = "E:\Certificate.P12"
- '导入证书
- Dim x509 As New Security.Cryptography.X509Certificates.X509Certificate2(certificatePath, "Import Password")
- Dim privateKey As Security.Cryptography.RSACryptoServiceProvider = x509.PrivateKey
- Dim publicKey As String = x509.PublicKey.Key.ToXmlString(False)
- '证书公钥加密
- Dim oRsaEncode As New Security.Cryptography.RSACryptoServiceProvider
- oRsaEncode.FromXmlString(publicKey)
- Dim resultBytes As Byte() = oRsaEncode.Encrypt(messageBytes, False)
- '证书私钥解密
- Dim oRsaDecode As Security.Cryptography.RSACryptoServiceProvider = DirectCast(privateKey, Security.Cryptography.RSACryptoServiceProvider)
- messageBytes = oRsaDecode.Decrypt(resultBytes, False)
- '返回结果
- Return Text.Encoding.UTF8.GetString(messageBytes)
5、用证书对文件加密解密
因为文件可能特别大 所以需要用流和 Buffer 的方式,如果把文件全部读到 Byte() 里进行加密,当文件很大,比如 5G,那全部读到 Byte() 里崩溃掉
- ''' <summary>用证书加密文件</summary>
- ''' <param name="certificatePath">证书路径</param>
- ''' <param name="certificatePassword">证书导入密码</param>
- ''' <param name="sourcePath">需要加密的文件路径</param>
- ''' <param name="targetPath">加密后的文件路径</param>
- ''' <remarks></remarks>
- Public Sub Encrypt(ByVal certificatePath As String, ByVal certificatePassword As String, ByVal sourcePath As String, ByVal targetPath As String)
- '导入证书
- Dim x509 As New Security.Cryptography.X509Certificates.X509Certificate2(certificatePath, certificatePassword)
- 'Dim privateKey As Security.Cryptography.RSACryptoServiceProvider = x509.PrivateKey
- Dim publicKey As String = x509.PublicKey.Key.ToXmlString(False)
- Dim oRsa As New Security.Cryptography.RSACryptoServiceProvider()
- oRsa.FromXmlString(publicKey)
- Dim sourceStream As New System.IO.FileStream(sourcePath, System.IO.FileMode.Open)
- Dim targetStream As New System.IO.FileStream(targetPath, System.IO.FileMode.OpenOrCreate)
- Dim blockSize As Integer = 0
- If oRsa.KeySize = 1024 Then
- blockSize = 16
- Else
- blockSize = 8
- End If
- Dim K As Integer = 1
- While K > 0
- Dim buffer As Byte() = New Byte(blockSize - 1) {}
- K = sourceStream.Read(buffer, 0, buffer.Length)
- If K > 0 Then
- Dim buffer1 As Byte(), encryblock As Byte()
- If blockSize = K Then
- encryblock = oRsa.Encrypt(buffer, False)
- targetStream.Write(encryblock, 0, encryblock.Length)
- Else
- buffer1 = New Byte(K - 1) {}
- For i As Integer = 0 To K - 1
- buffer1(i) = buffer(i)
- Next
- encryblock = oRsa.Encrypt(buffer1, False)
- targetStream.Write(encryblock, 0, encryblock.Length)
- End If
- Else
- sourceStream.Close()
- targetStream.Close()
- End If
- End While
- End Sub
- ''' <summary>用证书解密文件</summary>
- ''' <param name="certificatePath">证书路径</param>
- ''' <param name="certificatePassword">证书导入密码</param>
- ''' <param name="sourcePath">需要解密的文件路径</param>
- ''' <param name="targetPath">解密后的文件路径</param>
- ''' <remarks></remarks>
- Public Sub Decrypt(ByVal certificatePath As String, ByVal certificatePassword As String, ByVal sourcePath As String, ByVal targetPath As String)
- '导入证书
- Dim x509 As New Security.Cryptography.X509Certificates.X509Certificate2(certificatePath, certificatePassword)
- Dim privateKey As Security.Cryptography.RSACryptoServiceProvider = x509.PrivateKey
- 'Dim publicKey As String = x509.PublicKey.Key.ToXmlString(False)
- Dim oRsa As Security.Cryptography.RSACryptoServiceProvider = DirectCast(privateKey, Security.Cryptography.RSACryptoServiceProvider)
- Dim sourceStream As New System.IO.FileStream(sourcePath, System.IO.FileMode.Open)
- Dim targetStream As New System.IO.FileStream(targetPath, System.IO.FileMode.OpenOrCreate)
- Dim blockSize As Integer = oRsa.KeySize / 8
- Dim buffer1 As Byte(), encryblock As Byte()
- Dim K As Integer = 1
- While K > 0
- Dim buffer As Byte() = New Byte(blockSize - 1) {}
- K = sourceStream.Read(Buffer, 0, Buffer.Length)
- If K > 0 Then
- If blockSize = K Then
- encryblock = oRsa.Decrypt(buffer, False)
- targetStream.Write(encryblock, 0, encryblock.Length)
- Else
- buffer1 = New Byte(K - 1) {}
- For i As Integer = 0 To K - 1
- buffer1(i) = buffer(i)
- Next
- encryblock = oRsa.Decrypt(buffer1, False)
- targetStream.Write(encryblock, 0, encryblock.Length)
- End If
- Else
- sourceStream.Close()
- targetStream.Close()
- End If
- End While
- End Sub
6、用证书对文件进行签名验签
- Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
- x509 = New X509Certificate2(Path, "12345678")
- SignFile("1.txt", "11.txt")
- VerifyFile("1.txt", "11.txt")
- End Sub
- Private Function VerifyFile(ByVal FileName As String, ByVal SignedFileName As String) As Boolean
- Dim reslut As Boolean = True
- Dim objread As New System.IO.StreamReader(FileName)
- Dim objreadSigned As New System.IO.StreamReader(SignedFileName)
- Dim VeryRsa As New RSACryptoServiceProvider()
- VeryRsa.FromXmlString(x509.PublicKey.Key.ToXmlString(False))
- Dim Inblocksize As Integer = 0
- Dim Signedblocksize As Integer = 0
- If VeryRsa.KeySize = 1024 Then
- Inblocksize = 16
- Else
- Inblocksize = 8
- End If
- Signedblocksize = VeryRsa.KeySize / 8
- Dim Closed As Boolean = True
- Dim Buffer As Byte()
- '原文缓存区
- Dim InBuffer As Byte()
- '原文缓存区
- Dim Buffer1 As Byte()
- '签名文件缓存区
- While Closed
- Buffer = Nothing
- Buffer = New Byte(Inblocksize - 1) {}
- Dim k As Integer = objread.BaseStream.Read(Buffer, 0, Buffer.Length)
- If k > 0 Then
- If Inblocksize = k Then
- '读出来的长度和缓存区一样大
- Buffer1 = New Byte(Signedblocksize - 1) {}
- objreadSigned.BaseStream.Read(Buffer1, 0, Buffer1.Length)
- reslut = VeryRsa.VerifyData(Buffer, "SHA1", Buffer1)
- If Not reslut Then
- Closed = False
- End If
- Else
- '意思是Buffer没满,只有k个字节,k字节后面全是空所以不需要验签
- InBuffer = New Byte(k - 1) {}
- For i As Integer = 0 To k - 1
- InBuffer(i) = Buffer(i)
- Next
- Buffer1 = New Byte(Signedblocksize - 1) {}
- objreadSigned.BaseStream.Read(Buffer1, 0, Buffer1.Length)
- reslut = VeryRsa.VerifyData(InBuffer, "SHA1", Buffer1)
- If Not reslut Then
- Closed = False
- End If
- End If
- Else
- '这里的意思是原文已经读完毕了,并且已经和签名文件对应验签成功,那么
- '签名文件也必须读完毕了。
- If objreadSigned.BaseStream.Position <> objreadSigned.BaseStream.Length Then
- reslut = False
- End If
- objreadSigned.Close()
- objread.Close()
- Closed = False
- End If
- End While
- Return reslut
- End Function
- Private Sub SignFile(ByVal InFileName As String, ByVal OutFileName As String)
- Dim SignRsa As RSACryptoServiceProvider = DirectCast(x509.PrivateKey, RSACryptoServiceProvider)
- Dim objread As New System.IO.StreamReader(InFileName)
- Dim objwrite As New System.IO.StreamWriter(OutFileName, False)
- Dim blocksize As Integer = 0
- If SignRsa.KeySize = 1024 Then
- blocksize = 16
- Else
- blocksize = 8
- End If
- Dim Closed As Boolean = True
- Dim Buffer As Byte() = New Byte(blocksize - 1) {}
- Dim buffer1 As Byte(), SignBytes As Byte()
- While Closed
- Dim k As Integer = objread.BaseStream.Read(Buffer, 0, Buffer.Length)
- If k > 0 Then
- If k = blocksize Then
- SignBytes = SignRsa.SignData(Buffer, "SHA1")
- objwrite.BaseStream.Write(SignBytes, 0, SignBytes.Length)
- Else
- buffer1 = New Byte(k - 1) {}
- For i As Integer = 0 To k - 1
- buffer1(i) = Buffer(i)
- Next
- SignBytes = SignRsa.SignData(buffer1, "SHA1")
- objwrite.BaseStream.Write(SignBytes, 0, SignBytes.Length)
- End If
- Else
- Closed = False
- objread.Close()
- objwrite.Close()
- End If
- End While
- End Sub
· 本文由 木炭 发布在《激情燃烧的木炭》 上,原文地址为:http://www.woodcoal.cn/technology/visual-basic/2009331-18230-499.html(转载请保留本信息、全文内容和链接)
关于本文
- 作者:
- 来源:
- 时间:2009/03/31
- 关键词:非对称加密 加密 解密 签名 算法 验签 证书
- 栏 目:Visual Basic
- 上一篇:带进度条的ListView,在Item中直接画Progress
- 下一篇:利用 RSA 非对称密钥 SignedXML 来实现简单的软件授权
发表评论