microsoft-visualbasic-runtime/ApplicationServices/Tools/Network/SSL/Certificate.vb

279 lines
12 KiB
VB.net
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#Region "Microsoft.VisualBasic::56424bbe3437e0f8e2bdd340bb3cb693, Microsoft.VisualBasic.Core\ApplicationServices\Tools\Network\SSL\Certificate.vb"
' Author:
'
' asuka (amethyst.asuka@gcmodeller.org)
' xie (genetics@smrucc.org)
' xieguigang (xie.guigang@live.com)
'
' Copyright (c) 2018 GPL3 Licensed
'
'
' GNU GENERAL PUBLIC LICENSE (GPL3)
'
'
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
'
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
' GNU General Public License for more details.
'
' You should have received a copy of the GNU General Public License
' along with this program. If not, see <http://www.gnu.org/licenses/>.
' /********************************************************************************/
' Summaries:
' Class Certificate
'
' Properties: AppDomain, hash, IsPublicToken, PrivateKey, uid
'
' Constructor: (+4 Overloads) Sub New
' Function: __decrypt, __load, (+2 Overloads) CopyFrom, (+2 Overloads) Decrypt, DecryptString
' (+2 Overloads) Encrypt, EncryptData, (+2 Overloads) Install, InstallPublicToken, PublicEncrypt
' ToString
'
'
' /********************************************************************************/
#End Region
Imports Microsoft.VisualBasic.Emit.CodeDOM_VBC
Imports Microsoft.VisualBasic.Net.Protocols
Imports Microsoft.VisualBasic.SecurityString
Namespace Net.SSL
''' <summary>
''' 应用程序的完整性验证和用户身份的验证
''' </summary>
Public Class Certificate : Implements SecurityString.SecurityStringModel.ISecurityStringModel
Protected _SHA256 As SecurityString.SHA256
''' <summary>
''' 私有密匙
''' </summary>
''' <returns></returns>
Public Overridable ReadOnly Property PrivateKey As String
Get
Return _SHA256.strPassphrase
End Get
End Property
''' <summary>
''' <see cref="Guid"/>计算出来的哈希值只能为负数现在约定当这个属性为0的时候就认为这个证书是公共密匙
''' 这个一般是使用用户的账号所计算出来的哈希值
''' </summary>
''' <returns></returns>
Public ReadOnly Property uid As Long
Get
Return _uid
End Get
End Property
''' <summary>
''' 初始化继承类所需要的
''' </summary>
Protected _uid As Long
Public ReadOnly Property IsPublicToken As Boolean
Get
Return uid = 0L
End Get
End Property
''' <summary>
''' 与<see cref="uid"/>属性所不同的是,这个属性是<see cref="privatekey"/>的哈希值,
''' 通常这个哈希值在请求resultful WebAPI的时候用来作为用户的唯一标识
''' </summary>
''' <returns></returns>
Public ReadOnly Property hash As Long
Public Overrides Function ToString() As String
Return $"[{NameOf(Certificate)}] {uid} {_SHA256.Passphrase}"
End Function
''' <summary>
''' 请注意这个构造方法会计算一遍密码的哈希值,假若需要直接进行初始化,请使用<see cref="Install"/>方法
''' </summary>
''' <param name="hash">用户的私有密匙</param>
''' <param name="uid">大小写无关的</param>
Sub New(hash As String, uid As String)
hash = SecurityString.MD5Hash.GetMd5Hash(hash)
_SHA256 = New SecurityString.SHA256(hash, SALT)
Me._uid = SecurityString.MD5Hash.ToLong(SecurityString.MD5Hash.GetMd5Hash(uid.ToLower))
Me.hash = SecurityString.MD5Hash.ToLong(hash)
End Sub
''' <summary>
'''
''' </summary>
''' <param name="hash">原始的密码,会在这个构造函数之中计算为哈希值产生新的密码。</param>
''' <param name="uid">客户端所发送过来的使用哈希值计算出来的唯一标识符</param>
Sub New(hash As String, uid As Long)
hash = SecurityString.MD5Hash.GetMd5Hash(hash)
_SHA256 = New SecurityString.SHA256(hash, SALT)
Me._uid = uid
Me.hash = SecurityString.MD5Hash.ToLong(hash)
End Sub
''' <summary>
''' 从服务器上面所返回来的握手数据
''' </summary>
''' <param name="handshakeData"></param>
Sub New(handshakeData As RequestStream)
Dim hash As String = SecurityString.MD5Hash.GetMd5Hash(handshakeData.GetUTF8String)
_SHA256 = New SHA256(hash, SALT)
Me._uid = handshakeData.uid
Me.hash = SecurityString.MD5Hash.ToLong(hash)
End Sub
''' <summary>
''' 这个构造函数不再计算哈希值而是直接初始化
''' </summary>
''' <param name="hash">必须是md5哈希值</param>
Protected Sub New(hash As String)
_SHA256 = New SHA256(hash, SALT)
Me.hash = SecurityString.MD5Hash.ToLong(hash)
End Sub
Const SALT As String = "88888888"
Public Shared Function CopyFrom(CA As SSL.Certificate, uid As String) As SSL.Certificate
Dim hashCode As String = SecurityString.MD5Hash.ToLong(SecurityString.MD5Hash.GetMd5Hash(uid.ToLower))
Return New SSL.Certificate(CA._SHA256.Passphrase) With {._uid = hashCode}
End Function
Public Shared Function CopyFrom(CA As SSL.Certificate, uid As Long) As SSL.Certificate
Return New SSL.Certificate(CA._SHA256.Passphrase) With {._uid = uid}
End Function
''' <summary>
''' 不计算密匙<paramref name="privateKey"/>哈希值而是直接安装
''' </summary>
''' <param name="privateKey"></param>
''' <param name="uid"></param>
''' <returns></returns>
Public Shared Function Install(privateKey As String, uid As Long) As SSL.Certificate
Return New SSL.Certificate(privateKey) With {._uid = uid}
End Function
Public Shared Function InstallPublicToken(publicKey As String) As SSL.Certificate
Call $"Install public token ssl certificate.".__DEBUG_ECHO
Return New SSL.Certificate(publicKey)
End Function
''' <summary>
''' 函数会根据uid的值来设定协议为私有密匙还是公共密匙
''' </summary>
''' <param name="request"></param>
''' <returns></returns>
Public Overridable Function Encrypt(request As RequestStream) As RequestStream
Dim byteData As Byte() = request.Serialize
Dim Protocol = If(IsPublicToken, RequestStream.Protocols.SSL_PublicToken, RequestStream.Protocols.SSL)
byteData = _SHA256.Encrypt(byteData)
request = New RequestStream(RequestStream.SYS_PROTOCOL, Protocol, byteData) With {.uid = uid}
Return request
End Function
''' <summary>
''' 强制将协议设定为公共密匙加密
''' </summary>
''' <param name="request"></param>
''' <returns></returns>
Public Overridable Function PublicEncrypt(request As RequestStream) As RequestStream
Dim byteData As Byte() = request.Serialize
byteData = _SHA256.Encrypt(byteData)
request = New RequestStream(RequestStream.SYS_PROTOCOL, RequestStream.Protocols.SSL_PublicToken, byteData) With {.uid = uid}
Return request
End Function
''' <summary>
''' <see cref="Decrypt(Byte())"/> <see cref="RequestStream.ChunkBuffer"/>
''' </summary>
''' <param name="request"></param>
''' <returns></returns>
Public Overridable Function Decrypt(request As RequestStream) As RequestStream
Return __decrypt(request, _SHA256)
End Function
Protected Shared Function __decrypt(request As RequestStream, sha256 As SecurityString.SHA256) As RequestStream
Dim byteData As Byte() = request.ChunkBuffer
byteData = sha256.Decrypt(byteData)
request = New RequestStream(byteData)
Return request
End Function
''' <summary>
''' 检查应用程序的完整性
''' </summary>
''' <returns></returns>
Public Shared ReadOnly Property AppDomain As Certificate = Install(App.ExecutablePath, publicToken:=True)
''' <summary>
'''
''' </summary>
''' <param name="App">可执行程序的文件路径</param>
''' <returns></returns>
Public Shared Function Install(App As String, Optional publicToken As Boolean = False) As Certificate
Call Console.WriteLine()
Call Console.WriteLine()
Call $"**************************************************[ INSTALL {NameOf(Certificate)}: {App.ToFileURL}]****************************************************************".__DEBUG_ECHO
Dim Modules = (From [module] As String
In __load(App).AsParallel
Select [module], hash = SecurityString.MD5Hash.GetFileHashString([module])
Order By hash Ascending).ToArray '????已经排过序了,为什么顺序还是不一样
For Each [module] In Modules
Call $" Installed Module ==> {[module].ToString}".__DEBUG_ECHO
Next
Dim caHashString As String = String.Join("+", (From [mod] In Modules Select [mod].hash).ToArray)
Dim CA As Certificate = If(publicToken, Certificate.InstallPublicToken(SecurityString.GetMd5Hash(caHashString)), New Certificate(caHashString, NameOf(App)))
Call Console.WriteLine()
Call Console.WriteLine()
Call $"**************************************************[ END OF INSTALL {NameOf(Certificate)} ==> {CA.ToString}]****************************************************************".__DEBUG_ECHO
Return CA
End Function
Private Shared Function __load(path As String) As String()
Dim assembly As System.Reflection.Assembly
Try
assembly = System.Reflection.Assembly.LoadFile(FileIO.FileSystem.GetFileInfo(path).FullName)
Catch ex As Exception
Throw New Exception(path.ToFileURL, ex)
End Try
Dim refListBuffer = GetReferences(assembly:=assembly, removeSystem:=True)
Return refListBuffer
End Function
Public Overridable Function Decrypt(input() As Byte) As Byte() Implements SecurityStringModel.ISecurityStringModel.Decrypt
Return _SHA256.Decrypt(input)
End Function
Public Overridable Function DecryptString(text As String) As String Implements SecurityStringModel.ISecurityStringModel.DecryptString
Return _SHA256.DecryptString(text)
End Function
Public Overridable Function Encrypt(input() As Byte) As Byte() Implements SecurityStringModel.ISecurityStringModel.Encrypt
Return _SHA256.Encrypt(input)
End Function
Public Overridable Function EncryptData(text As String) As String Implements SecurityStringModel.ISecurityStringModel.EncryptData
Return _SHA256.EncryptData(text)
End Function
End Class
End Namespace