Re: [RESOLVED] clsCrypt.cls
Sorry for the late reply but found this in an unclosed IDE and will post this for posterity.
Code:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function BCryptOpenAlgorithmProvider Lib "bcrypt" (ByRef hAlgorithm As Long, ByVal pszAlgId As Long, ByVal pszImplementation As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptCloseAlgorithmProvider Lib "bcrypt" (ByVal hAlgorithm As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptDestroyKey Lib "bcrypt" (ByVal hKey As Long) As Long
Private Declare Function BCryptSetProperty Lib "bcrypt" (ByVal hObject As Long, ByVal pszProperty As Long, ByVal pbInput As Long, ByVal cbInput As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptGenerateSymmetricKey Lib "bcrypt" (ByVal hAlgorithm As Long, hKey As Long, ByVal pbKeyObject As Long, ByVal cbKeyObject As Long, ByVal pbSecret As Long, ByVal cbSecret As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptDecrypt Lib "bcrypt" (ByVal hKey As Long, ByVal pbInput As Long, ByVal cbInput As Long, ByVal pPaddingInfo As Long, ByVal pbIV As Long, ByVal cbIV As Long, ByVal pbOutput As Long, ByVal cbOutput As Long, cbResult As Long, ByVal dwFlags As Long) As Long
Private Type BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO
cbSize As Long
dwInfoVersion As Long
pbNonce As Long
cbNonce As Long
pbAuthData As Long
cbAuthData As Long
pbTag As Long
cbTag As Long
pbMacContext As Long
cbMacContext As Long
cbAAD As Long
lPad As Long
cbData(7) As Byte
dwFlags As Long
lPad2 As Long
End Type
Private Function pvCryptoAeadAesGcmDecrypt( _
baKey() As Byte, baIV() As Byte, _
baBuffer() As Byte, ByVal lPos As Long, ByVal lSize As Long, _
baTag() As Byte, ByVal lTagPos As Long, ByVal lTagSize As Long, _
baAad() As Byte, ByVal lAadPos As Long, ByVal lAdSize As Long) As Boolean
Dim hResult As Long
Dim sApiSource As String
Dim hAlg As Long
Dim hKey As Long
Dim uInfo As BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO
Dim lResult As Long
hResult = BCryptOpenAlgorithmProvider(hAlg, StrPtr("AES"), 0, 0)
If hResult < 0 Then
sApiSource = "BCryptOpenAlgorithmProvider"
GoTo QH
End If
hResult = BCryptSetProperty(hAlg, StrPtr("ChainingMode"), StrPtr("ChainingModeGCM"), 32, 0)
If hResult < 0 Then
GoTo QH
End If
hResult = BCryptGenerateSymmetricKey(hAlg, hKey, 0, 0, VarPtr(baKey(0)), UBound(baKey) + 1, 0)
If hResult < 0 Then
GoTo QH
End If
With uInfo
.cbSize = LenB(uInfo)
.dwInfoVersion = 1
.pbNonce = VarPtr(baIV(0))
.cbNonce = UBound(baIV) + 1
If lAdSize > 0 Then
.pbAuthData = VarPtr(baAad(lAadPos))
.cbAuthData = lAdSize
End If
.pbTag = VarPtr(baTag(lTagPos))
.cbTag = lTagSize
End With
hResult = BCryptDecrypt(hKey, VarPtr(baBuffer(lPos)), lSize, VarPtr(uInfo), 0, 0, VarPtr(baBuffer(lPos)), lSize, lResult, 0)
If hResult < 0 Then
GoTo QH
End If
Debug.Assert lResult = lSize
'--- success
pvCryptoAeadAesGcmDecrypt = True
QH:
If hKey <> 0 Then
Call BCryptDestroyKey(hKey)
End If
If hAlg <> 0 Then
Call BCryptCloseAlgorithmProvider(hAlg, 0)
End If
If hResult < 0 Then
Err.Raise hResult
End If
End Function
Private Function DecodePassword(baBuffer() As Byte, baMasterKey() As Byte) As String
Dim baIV() As Byte
Dim baCipherText() As Byte
Dim baEmpty() As Byte
ReDim baIV(0 To 11) As Byte
Call CopyMemory(baIV(0), baBuffer(3), UBound(baIV) + 1)
ReDim baCipherText(0 To UBound(baBuffer) - 15 - 16) As Byte
Call CopyMemory(baCipherText(0), baBuffer(15), UBound(baCipherText) + 1)
If Not pvCryptoAeadAesGcmDecrypt(baMasterKey, baIV, baCipherText, 0, UBound(baCipherText) + 1, baBuffer, UBound(baBuffer) - 15, 16, baEmpty, 0, 0) Then
GoTo QH
End If
DecodePassword = StrConv(baCipherText, vbUnicode)
QH:
End Function
Private Sub Form_Load()
Const PassCrypt = "76313076F0C9F33DA5EEB1F7979B63589D0D01793F3B6289EBE350A4E990A0C6D9160C77A0CA13C4040B60"
Const MasterKey = "4405A103B2E0B0C6DC3E4EBB3DFAC7F6F3B47993286F3B009B119CEF6BD7985E"
Const PassDecrypt = "GxFcyBxI2oty"
Dim bArrPassCrypt() As Byte
Dim bArrKey() As Byte
Call HexToByte(PassCrypt, bArrPassCrypt)
Call HexToByte(MasterKey, bArrKey)
Debug.Assert DecodePassword(bArrPassCrypt, bArrKey) = PassDecrypt
End Sub
Public Function HexToByte(HexStr As String, bHex() As Byte) As Boolean
Dim lLen As Long
Dim lPntr As Long
Dim bTmp() As Byte
If Len(HexStr) > 1 Then
lLen = Len(HexStr) / 2
ReDim bHex(lLen - 1)
For lPntr = 0 To UBound(bHex)
bHex(lPntr) = Val("&H" & Mid$(HexStr, lPntr * 2 + 1, 2))
Next lPntr
HexToByte = True
Else
bHex = bTmp
End If
End Function
The pvCryptoAeadAesGcmDecrypt helper function above is all you need to use BCrypt (so called CNG system API) to implement AES in GCM mode which is a kind of AEAD cipher i.e. it needs a key, a nonce (so called IV) and can include an additional associated data which is not encrypted but becomes part of the message authentication hash (so called MAC) besides the plaintext.
The helper above decrypts in-place i.e. the ciphertext in baBuffer is decrypted to plaintext again in baBuffer but lAdSize can be zero to skip on additional associated data (as in your case).
cheers,
</wqw>
Re: [RESOLVED] clsCrypt.cls
Quote:
Originally Posted by
wqweto
Sorry for the late reply but found this in an unclosed IDE and will post this for posterity.
Code:
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function BCryptOpenAlgorithmProvider Lib "bcrypt" (ByRef hAlgorithm As Long, ByVal pszAlgId As Long, ByVal pszImplementation As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptCloseAlgorithmProvider Lib "bcrypt" (ByVal hAlgorithm As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptDestroyKey Lib "bcrypt" (ByVal hKey As Long) As Long
Private Declare Function BCryptSetProperty Lib "bcrypt" (ByVal hObject As Long, ByVal pszProperty As Long, ByVal pbInput As Long, ByVal cbInput As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptGenerateSymmetricKey Lib "bcrypt" (ByVal hAlgorithm As Long, hKey As Long, ByVal pbKeyObject As Long, ByVal cbKeyObject As Long, ByVal pbSecret As Long, ByVal cbSecret As Long, ByVal dwFlags As Long) As Long
Private Declare Function BCryptDecrypt Lib "bcrypt" (ByVal hKey As Long, ByVal pbInput As Long, ByVal cbInput As Long, ByVal pPaddingInfo As Long, ByVal pbIV As Long, ByVal cbIV As Long, ByVal pbOutput As Long, ByVal cbOutput As Long, cbResult As Long, ByVal dwFlags As Long) As Long
Private Type BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO
cbSize As Long
dwInfoVersion As Long
pbNonce As Long
cbNonce As Long
pbAuthData As Long
cbAuthData As Long
pbTag As Long
cbTag As Long
pbMacContext As Long
cbMacContext As Long
cbAAD As Long
lPad As Long
cbData(7) As Byte
dwFlags As Long
lPad2 As Long
End Type
Private Function pvCryptoAeadAesGcmDecrypt( _
baKey() As Byte, baIV() As Byte, _
baBuffer() As Byte, ByVal lPos As Long, ByVal lSize As Long, _
baTag() As Byte, ByVal lTagPos As Long, ByVal lTagSize As Long, _
baAad() As Byte, ByVal lAadPos As Long, ByVal lAdSize As Long) As Boolean
Dim hResult As Long
Dim sApiSource As String
Dim hAlg As Long
Dim hKey As Long
Dim uInfo As BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO
Dim lResult As Long
hResult = BCryptOpenAlgorithmProvider(hAlg, StrPtr("AES"), 0, 0)
If hResult < 0 Then
sApiSource = "BCryptOpenAlgorithmProvider"
GoTo QH
End If
hResult = BCryptSetProperty(hAlg, StrPtr("ChainingMode"), StrPtr("ChainingModeGCM"), 32, 0)
If hResult < 0 Then
GoTo QH
End If
hResult = BCryptGenerateSymmetricKey(hAlg, hKey, 0, 0, VarPtr(baKey(0)), UBound(baKey) + 1, 0)
If hResult < 0 Then
GoTo QH
End If
With uInfo
.cbSize = LenB(uInfo)
.dwInfoVersion = 1
.pbNonce = VarPtr(baIV(0))
.cbNonce = UBound(baIV) + 1
If lAdSize > 0 Then
.pbAuthData = VarPtr(baAad(lAadPos))
.cbAuthData = lAdSize
End If
.pbTag = VarPtr(baTag(lTagPos))
.cbTag = lTagSize
End With
hResult = BCryptDecrypt(hKey, VarPtr(baBuffer(lPos)), lSize, VarPtr(uInfo), 0, 0, VarPtr(baBuffer(lPos)), lSize, lResult, 0)
If hResult < 0 Then
GoTo QH
End If
Debug.Assert lResult = lSize
'--- success
pvCryptoAeadAesGcmDecrypt = True
QH:
If hKey <> 0 Then
Call BCryptDestroyKey(hKey)
End If
If hAlg <> 0 Then
Call BCryptCloseAlgorithmProvider(hAlg, 0)
End If
If hResult < 0 Then
Err.Raise hResult
End If
End Function
Private Function DecodePassword(baBuffer() As Byte, baMasterKey() As Byte) As String
Dim baIV() As Byte
Dim baCipherText() As Byte
Dim baEmpty() As Byte
ReDim baIV(0 To 11) As Byte
Call CopyMemory(baIV(0), baBuffer(3), UBound(baIV) + 1)
ReDim baCipherText(0 To UBound(baBuffer) - 15 - 16) As Byte
Call CopyMemory(baCipherText(0), baBuffer(15), UBound(baCipherText) + 1)
If Not pvCryptoAeadAesGcmDecrypt(baMasterKey, baIV, baCipherText, 0, UBound(baCipherText) + 1, baBuffer, UBound(baBuffer) - 15, 16, baEmpty, 0, 0) Then
GoTo QH
End If
DecodePassword = StrConv(baCipherText, vbUnicode)
QH:
End Function
Private Sub Form_Load()
Const PassCrypt = "76313076F0C9F33DA5EEB1F7979B63589D0D01793F3B6289EBE350A4E990A0C6D9160C77A0CA13C4040B60"
Const MasterKey = "4405A103B2E0B0C6DC3E4EBB3DFAC7F6F3B47993286F3B009B119CEF6BD7985E"
Const PassDecrypt = "GxFcyBxI2oty"
Dim bArrPassCrypt() As Byte
Dim bArrKey() As Byte
Call HexToByte(PassCrypt, bArrPassCrypt)
Call HexToByte(MasterKey, bArrKey)
Debug.Assert DecodePassword(bArrPassCrypt, bArrKey) = PassDecrypt
End Sub
Public Function HexToByte(HexStr As String, bHex() As Byte) As Boolean
Dim lLen As Long
Dim lPntr As Long
Dim bTmp() As Byte
If Len(HexStr) > 1 Then
lLen = Len(HexStr) / 2
ReDim bHex(lLen - 1)
For lPntr = 0 To UBound(bHex)
bHex(lPntr) = Val("&H" & Mid$(HexStr, lPntr * 2 + 1, 2))
Next lPntr
HexToByte = True
Else
bHex = bTmp
End If
End Function
The
pvCryptoAeadAesGcmDecrypt helper function above is all you need to use BCrypt (so called CNG system API) to implement AES in GCM mode which is a kind of AEAD cipher i.e. it needs a key, a nonce (so called IV) and can include an additional associated data which is not encrypted but becomes part of the message authentication hash (so called MAC) besides the plaintext.
The helper above decrypts in-place i.e. the ciphertext in baBuffer is decrypted to plaintext again in baBuffer but lAdSize can be zero to skip on additional associated data (as in your case).
cheers,
</wqw>
Perfect!!, I had already summarized enough but, you have simplified it much more!!,i just make some changes to personal necessity since my source is a DATA_BLOB so not to dump a byte array pass and use pointers.
Code:
Private Function pvCryptoAeadAesGcmDecrypt(baKey() As Byte, pCryptData As Long, lSize As Long, pIV As Long, pTag As Long, baDecriptText() As Byte) As Boolean
Dim hAlg As Long
Dim hKey As Long
Dim uInfo As BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO
Dim lResult As Long
ReDim baDecriptText(lSize - 1)
With uInfo
.cbSize = Len(uInfo)
.dwInfoVersion = 1
.pbNonce = pIV
.cbNonce = 12
.pbTag = pTag
.cbTag = 16
End With
If BCryptOpenAlgorithmProvider(hAlg, StrPtr("AES"), 0, 0) = 0& Then
If BCryptSetProperty(hAlg, StrPtr("ChainingMode"), StrPtr("ChainingModeGCM"), 32, 0) = 0& Then
If BCryptGenerateSymmetricKey(hAlg, hKey, 0, 0, VarPtr(baKey(0)), UBound(baKey) + 1, 0) = 0& Then
If BCryptDecrypt(hKey, pCryptData, lSize, VarPtr(uInfo), 0, 0, VarPtr(baDecriptText(0)), lSize, lResult, 0) = 0& Then
pvCryptoAeadAesGcmDecrypt = CBool(lResult = lSize)
End If
Call BCryptDestroyKey(hKey)
End If
End If
Call BCryptCloseAlgorithmProvider(hAlg, 0)
End If
End Function
Code:
With BLOBIN
If .cbData > 0 Then
ReDim bHeader(2)
CopyMemory bHeader(0), ByVal .pbData, 3
If (bHeader(0) Or bHeader(1) Or bHeader(2)) = &H77 Then
If .cbData > 31 Then
If pvCryptoAeadAesGcmDecrypt(bKey, .pbData + 15, .cbData - 31, .pbData + 3, .pbData + .cbData - 16, bPass) Then
PASSWORD = StrConv(bPass, vbUnicode)
End If
End If
Else
If CryptUnprotectData(BLOBIN, 0&, 0&, 0&, 0&, 8, BLOBOUT) Then
PASSWORD = ReadBlobString(BLOBOUT)
End If
End If
End If
End With
whatever observations you have, it's always good to listen to learn
Re: [RESOLVED] clsCrypt.cls
@LeanDroA; Can you post the GetbSize routine?
Re: [RESOLVED] clsCrypt.cls
I assume it's something like this
Code:
Public Function GetbSize(btArray() As Byte) As Long
GetbSize= UBound(btArray) - LBound(btArray) + 1
End Function
Re: [RESOLVED] clsCrypt.cls
Quote:
Originally Posted by
Juggler_IN
@LeanDroA; Can you post the GetbSize routine?
The SimpleSock.zip download at:
https://www.vbforums.com/showthread....B6-Simple-Sock
contains the entire clsCrypt.cls class including the GetbSize routine.
Code:
Public Function GetbSize(bArray() As Byte) As Long
On Error GoTo GetSizeErr
GetbSize = UBound(bArray) + 1
Exit Function
GetSizeErr:
GetbSize = 0
End Function
J.A. Coutts