2009-09-24 69 views
10

Sono interessato se è possibile eseguire la crittografia/decrittografia di stringhe utilizzando Excel Visual Basic e alcuni provider di servizi di crittografia.Crittografia e decrittografia delle stringhe in Excel

Ho trovato una soluzione Encrypting and Decrypting Strings in Visual Basic, ma sembra valida solo per Visual Basic autonomo.

Quindi mi suggerirei un altro metodo di crittografia o mostrare come la procedura dettagliata potrebbe essere adottata per Excel Visual Basic?

risposta

21

Il collegamento fornito mostra come eseguire la crittografia e la decrittografia delle stringhe utilizzando VB.NET e, quindi, utilizzando .NET Framework.

Attualmente, i prodotti Microsoft Office non possono ancora utilizzare il componente Visual Studio Tools for Applications che consentirà ai prodotti Office di accedere al BCL del framework .NET (librerie di classi di base) che, a sua volta, accedono al CSP di Windows (provider di server crittografici) e forniscono un bel wrapper attorno a quelle funzioni di crittografia/decrittografia.

Per il momento, i prodotti Office sono bloccati con il vecchio VBA (Visual Basic for Applications) che si basa sul vecchio VB6 (e precedenti) versioni di Visual Basic che si basano su di COM, piuttosto che il .NET Framework.

A causa di tutto ciò, sarà necessario chiamare l'API Win32 per accedere alle funzioni CSP, o sarà necessario "roll-your-own" metodo di crittografia in puro codice VB6/VBA, anche se questo è probabile che sia meno sicuro. Tutto dipende da quanto "sicuro" vorresti che fosse la tua crittografia.

Se si vuole "roll-proprio-" di routine di codifica/decodifica di base stringa, dare un'occhiata a questi link per iniziare:

Encrypt a String Easily
Better XOR Encryption with a readable string
vb6 - encryption function
Visual Basic 6/VBA String Encryption/Decryption Function

Se si desidera accedere all'API Win32 e utilizzare il CSP Windows sottostante (un'opzione molto più sicura), vedere questi collegamenti per informazioni dettagliate su come ottenere ciò:

How to encrypt a string in Visual Basic 6.0
Access to CryptEncrypt (CryptoAPI/WinAPI) functions in VBA

Questo ultimo anello è probabilmente quello che si vorrà e comprende un modulo completo di classe VBA per "avvolgere" le funzioni di Windows CSP.

+0

Grazie mille! Spiegazione molto dettagliata e alcuni link utili. Vorrei che tutte le risposte qui fossero come le tue. –

2

Creare un modulo di classe denominato clsCifrado:


Option Explicit 
Option Compare Binary 

Private clsClave As String 

Property Get Clave() As String 
    Clave = clsClave 
End Property 

Property Let Clave(value As String) 
    clsClave = value 
End Property 


Function Cifrar(Frase As String) As String 

    Dim Cachos() As Byte 
    Dim LaClave() As Byte 
    Dim i As Integer 
    Dim Largo As Integer 

    If Frase <> "" Then 
     Cachos() = StrConv(Frase, vbFromUnicode) 
     LaClave() = StrConv(clsClave, vbFromUnicode) 
     Largo = Len(clsClave) 

     For i = LBound(Cachos) To UBound(Cachos) 
      Cachos(i) = (Cachos(i) Xor LaClave(i Mod Largo)) + 34 
     Next i 

     Cifrar = StrConv(Cachos(), vbUnicode) 
    Else 
     Cifrar = "" 
    End If 

End Function 

Function Descifrar(Frase As String) As String 

    Dim Cachos() As Byte 
    Dim LaClave() As Byte 
    Dim i As Integer 
    Dim Largo As Integer 

    If Frase <> "" Then 
     Cachos() = StrConv(Frase, vbFromUnicode) 
     LaClave() = StrConv(clsClave, vbFromUnicode) 
     Largo = Len(clsClave) 

     For i = LBound(Cachos) To UBound(Cachos) 
      Cachos(i) = Cachos(i) - 34 
      Cachos(i) = (Cachos(i) Xor LaClave(i Mod Largo)) 
     Next i 

     Descifrar = StrConv(Cachos(), vbUnicode) 
    Else 
     Descifrar = "" 
    End If 

End Function 

Ora è possibile utilizzarlo nel codice:

di Cipher


Private Sub btnCifrar_Click() 

    Dim Texto As String 
    Dim cCifrado As clsCifrado 

    Set cCifrado = New clsCifrado 

    '---poner la contraseña 
    If tbxClave.Text = "" Then 
     MsgBox "The Password is missing" 
     End Sub 
    Else 
     cCifrado.Clave = tbxClave.Text 
    End If 

    '---Sacar los datos 
    Texto = tbxFrase.Text 

    '---cifrar el texto 
    Texto = cCifrado.Cifrar(Texto) 

    tbxFrase.Text = Texto 

End Sub 

Per descipher


Private Sub btnDescifrar_Click() 

    Dim Texto As String 
    Dim cCifrado As clsCifrado 

    Set cCifrado = New clsCifrado 

    '---poner la contraseña 
    If tbxClave.Text = "" Then 
     MsgBox "The Password is missing" 
     End Sub 
    Else 
     cCifrado.Clave = tbxClave.Text 
    End If 

    '---Sacar los datos 
    Texto = tbxFrase.Text 

    '---cifrar el texto 
    Texto = cCifrado.Descifrar(Texto) 

    tbxFrase.Text = Texto 
End Sub 
0

Ecco un symetric esempio di cifratura/decifratura di base:

Sub testit() 
    Dim inputStr As String 
    inputStr = "Hello world!" 

    Dim enctrypted As String, decrypted As String 
    encrypted = scramble(inputStr) 
    decrypted = scramble(encrypted) 
    Debug.Print encrypted 
    Debug.Print decrypted 
End Sub 


Function stringToByteArray(str As String) As Variant 
    Dim bytes() As Byte 
    bytes = str 
    stringToByteArray = bytes 
End Function 

Function byteArrayToString(bytes() As Byte) As String 
    Dim str As String 
    str = bytes 
    byteArrayToString = str 
End Function 


Function scramble(str As String) As String 
    Const SECRET_PASSWORD As String = "K*4HD%f#nwS%sdf032#gfl!HLKN*pq7" 

    Dim stringBytes() As Byte, passwordBytes() As Byte 
    stringBytes = stringToByteArray(str) 
    passwordBytes = stringToByteArray(SECRET_PASSWORD) 

    Dim upperLim As Long 
    upperLim = UBound(stringBytes) 
    ReDim scrambledBytes(0 To upperLim) As Byte 
    Dim idx As Long 
    For idx = LBound(stringBytes) To upperLim 
     scrambledBytes(idx) = stringBytes(idx) Xor passwordBytes(idx) 
    Next idx 
    scramble = byteArrayToString(scrambledBytes) 
End Function 

Essere consapevoli del fatto che questo sarà in crash se il dato stringa di input è più lungo del secret_password . Questo è solo un esempio per iniziare.

1

È possibile chiamare i dati della cella excel tramite qualsiasi script di shell. Installare l'interfaccia di linguaggio R GPL Bert (http://bert-toolkit.com/) per Excel. Usa lo script R sotto in Excel per filtrare i dati della cella in Bash/perl/gpg/openssl.

c:\> cat c:\R322\callable_from_excel.R 
    CRYPTIT <- function(PLAINTEXT, MASTER_PASS) { 
    system(
     sprintf("bash -c 'echo '%s' | 
     gpg --symmetric --cipher-algo blowfish --force-mdc --passphrase '%s' -q | 
     base64 -w 0'", 
     PLAINTEXT, MASTER_PASS), 
     intern=TRUE) 
    } 

DECRYPTIT <- function(CRYPTTEXT, MASTER_PASS) { 
    system(
     sprintf("bash -c 'echo '%s'| 
     base64 -d | 
     gpg --passphrase '%s' -q | 
     putclip | getclip' ",CRYPTTEXT,MASTER_PASS), 
     intern=TRUE) 
    } 

In Excel, si può provare: C1 = CryptIt (A1, A2) e C2 = DECRYPTIT (C1, A2) Opzionale: putclip salva il testo decifrato negli Appunti. Entrambi i tipi di funzioni sono: String -> String. Avvertenze attuali sull'esclusione delle virgolette singole nelle stringhe con quotatura singola.

0

Questo codice funziona bene per me (3DES di crittografia/decrittografia):

devo conservare INITIALIZATION_VECTOR e TRIPLE_DES_KEY come variabili di ambiente (ovviamente valori diversi da quelli postato qui) e ottenere utilizzando la funzione VBA Environ(), quindi tutti i dati sensibili (password) nel codice VBA sono crittografati.

Option Explicit 

Public Const INITIALIZATION_VECTOR = "zlrs$5kd" 'Always 8 characters 

Public Const TRIPLE_DES_KEY = ">tlF8adk=35K{dsa" 'Always 16 characters 

Sub TestEncrypt() 
    MsgBox "This is an encrypted string: -> " & EncryptStringTripleDES("This is an encrypted string:") 
    Debug.Print EncryptStringTripleDES("This is an encrypted string:") 
End Sub 

Sub TestDecrypt() 
    MsgBox "u99CVItCGiMQEVYHf8+S22QbJ5CPQGDXuS5n1jvEIgU= -> " & DecryptStringTripleDES("u99CVItCGiMQEVYHf8+S22QbJ5CPQGDXuS5n1jvEIgU=") 
End Sub 


Function EncryptStringTripleDES(plain_string As String) As Variant 

    Dim encryption_object As Object 
    Dim plain_byte_data() As Byte 
    Dim encrypted_byte_data() As Byte 
    Dim encrypted_base64_string As String 

    EncryptStringTripleDES = Null 

    On Error GoTo FunctionError 

    plain_byte_data = CreateObject("System.Text.UTF8Encoding").GetBytes_4(plain_string) 

    Set encryption_object = CreateObject("System.Security.Cryptography.TripleDESCryptoServiceProvider") 
    encryption_object.Padding = 3 
    encryption_object.key = CreateObject("System.Text.UTF8Encoding").GetBytes_4(TRIPLE_DES_KEY) 
    encryption_object.IV = CreateObject("System.Text.UTF8Encoding").GetBytes_4(INITIALIZATION_VECTOR) 
    encrypted_byte_data = _ 
      encryption_object.CreateEncryptor().TransformFinalBlock(plain_byte_data, 0, UBound(plain_byte_data) + 1) 

    encrypted_base64_string = BytesToBase64(encrypted_byte_data) 

    EncryptStringTripleDES = encrypted_base64_string 

    Exit Function 

FunctionError: 

    MsgBox "TripleDES encryption failed" 

End Function 

Function DecryptStringTripleDES(encrypted_string As String) As Variant 

    Dim encryption_object As Object 
    Dim encrypted_byte_data() As Byte 
    Dim plain_byte_data() As Byte 
    Dim plain_string As String 

    DecryptStringTripleDES = Null 

    On Error GoTo FunctionError 

    encrypted_byte_data = Base64toBytes(encrypted_string) 

    Set encryption_object = CreateObject("System.Security.Cryptography.TripleDESCryptoServiceProvider") 
    encryption_object.Padding = 3 
    encryption_object.key = CreateObject("System.Text.UTF8Encoding").GetBytes_4(TRIPLE_DES_KEY) 
    encryption_object.IV = CreateObject("System.Text.UTF8Encoding").GetBytes_4(INITIALIZATION_VECTOR) 
    plain_byte_data = encryption_object.CreateDecryptor().TransformFinalBlock(encrypted_byte_data, 0, UBound(encrypted_byte_data) + 1) 

    plain_string = CreateObject("System.Text.UTF8Encoding").GetString(plain_byte_data) 

    DecryptStringTripleDES = plain_string 

    Exit Function 

FunctionError: 

    MsgBox "TripleDES decryption failed" 

End Function 


Function BytesToBase64(varBytes() As Byte) As String 
    With CreateObject("MSXML2.DomDocument").createElement("b64") 
     .DataType = "bin.base64" 
     .nodeTypedValue = varBytes 
     BytesToBase64 = Replace(.Text, vbLf, "") 
    End With 
End Function 


Function Base64toBytes(varStr As String) As Byte() 
    With CreateObject("MSXML2.DOMDocument").createElement("b64") 
     .DataType = "bin.base64" 
     .Text = varStr 
     Base64toBytes = .nodeTypedValue 
    End With 
End Function 

codice sorgente preso da qui: https://gist.github.com/motoraku/97ad730891e59159d86c

notare la differenza tra il codice originale e il mio codice, che è ulteriore opzione encryption_object.Padding = 3 che costringe VBA per non eseguire imbottitura. Con l'opzione padding impostata su 3 ottengo risultati esattamente come nell'implementazione C++ dell'algoritmo DES_ede3_cbc_encrypt e che è in accordo con quanto prodotto da questo online tool.

Problemi correlati