可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am looking to encrypt some data using Rijndael/AES in VBScript using a specific key and IV value. Are there any good function libraries or COM components that would be good to use?
I looked at CAPICOM; it allows a passphrase only, and won't allow setting specific key and IV values.
回答1:
One response suggested wrapping the RijndaelManaged
class in COM. You could also wrap some other AES implementation in COM. I just tried SlowAES, which is a JavaScript implementation of AES. Wrapping it in COM via a Windows Script Component makes it callable from VBScript. I would recommend this only if you cannot use the .NET approach; I would guess the AES for .NET will be faster than the AES implemented in JavaScript.
In my tests of the COM-wrapped-SlowAEs, I used CBC mode, and the encryption was completely compatible with the RijndaelManaged class in .NET.
Here's the WSC; I left out the 3 .js files provided by SlowAES. You need to insert them unchanged where I marked the file.
SlowAES is a Javascript implementation of AES. See http://code.google.com/p/slowaes. This is a COM package for SlowAES.
Save that to a file called SlowAES.wsc. Register it with "regsvr32 SlowAES.wsc." Here's some VBScript code that uses the component.
' ' ' byteArrayToHexString' ' convert a byte array to hex string.' ' ' Function byteArrayToHexString(a) Dim r,b,i r = "" For i = 0 To UBound(a) b = Hex( (a(i) And &HF0) / 16) & Hex(a(i) And &HF) r= r & b Next byteArrayToHexString= r End Function ' ' ' hexStringToByteArray' ' convert a string of hex byts to a byte array' ' ' Function hexStringToByteArray(s) Dim r() ReDim r(Len(s)/2-1) Dim x For i = 0 To Len(s)-2 Step 2 x= "&H" & Mid(s,i+1,2) r(i/2) = CInt(x) Next hexStringToByteArray= r End Function Function DemoEncryption() WScript.echo "Testing Ionic.Com.SlowAES..." WScript.echo "key: " & byteArrayToHexString(key) WScript.echo "iv: " & byteArrayToHexString(iv) WScript.echo "key length: " & keyLengthInBytes & " bytes" WScript.echo "key length: " & (keyLengthInBytes*8) & " bits" WScript.echo "plaintext: " & plaintext WScript.echo "plaintext.length: " & Len(plaintext) WScript.echo "instantiate Ionic.Com.SlowAES" Dim aes set aes = CreateObject("Ionic.Com.SlowAES") WScript.echo "keysize" aes.KeySize = keyLengthInBytes * 8 WScript.echo "key" aes.Key = byteArrayToHexString(key) WScript.echo "iv " aes.IV= byteArrayToHexString(iv) WScript.echo "mode " aes.Mode = "CBC" WScript.echo "encrypting... " Dim result result= aes.EncryptString(plaintext) ' result is a comma-separated string ' ' if we Eval() on it we convert it to an array ' Dim expr expr = "Array(" & result & ")" result= Eval( expr ) WScript.echo "Cryptotext/Eval: " & byteArrayToHexString(result) WScript.echo "Cryptotext.length: " & UBound(result)+1 WScript.echo "decrypting... " Dim decrypted 'The javascript way to do this is to pass the byte array.' ' Like so:' ' var decrypted = aes.DecryptBytesToString(result);' ' ' 'This does not work from VBScript. So, convert to a hexstring,' 'pass the hex string, and then convert back, in the COM component.' decrypted= aes.DecryptHexString(byteArrayToHexString(result)) WScript.echo "decrypted: " & decrypted End Function dim plaintext, iv, key, keyLengthInBytes plaintext= "Hello. This is a test. of the emergency broadcasting system." ' iv must be a hexstring representation of an array of bytes, length=16' iv = hexStringToByteArray("feedbeeffeedbeefbaadf00dbaadf00d") ' key must be a hexstring representation of an array of bytes, length=16 or 32' key = hexStringToByteArray("cafebabe0099887766554433221100AA") keyLengthInBytes= UBound(key)+1 If Err.Number 0 Then Err.Clear Call DemoEncryption If (Err.Number 0) Then WScript.echo("Error: " & Err.Description)
If you also want a password-based key derivation capability, then you can grab the very succint JavaScript code for PBKDF2 here, and create another WSC for that, without too much trouble.
EDIT: I did what I described - grabbed the source for PBKDF2 and integrated it into the code for SlowAES. I also produced a second, independent implementation in C# that uses the built-in .NET class libraries to do the RFC 2898-key derivation and AES encryption.
The result is 3 test applications, one in C#, one in JavaScript and another in VBScript. The source is available. They all take the same set of arguments. They each use a RFC 2898-compliant key derivation function. You can specify the password, salt, IV, and plaintext, as well as the number of RFC 2898 iterations to use in the PBKDF2. You can easily verify that the ciphertext is the same for each of these test programs. Maybe this example will be useful for someone.
回答2:
Old question- that really never gets old! One way is to declare encryption classes within vbscript, without needing external added COM objects or wrapper. The following example takes a string, encrypts and decrypts using Rijndael managed class:
'----------------------------------------------------- Dim obj,arr,i,r,str,enc,asc dim bytes,bytesd,s,sc,sd set obj=WScript.CreateObject("System.Security.Cryptography.RijndaelManaged") Set asc = CreateObject("System.Text.UTF8Encoding") s="This is a private message" bytes=asc.GetBytes_4(s) obj.GenerateKey() obj.GenerateIV() set enc=obj.CreateEncryptor() set dec=obj.CreateDecryptor() bytec=enc.TransformFinalBlock((bytes),0,lenb(bytes)) sc=asc.GetString((bytec)) msgbox sc byted=dec.TransformFinalBlock((bytec),0,lenb(bytec)) sd=asc.GetString((byted)) msgbox sd '-----------------------------------------------------
Best,
回答3:
Somebody wrote a short tutorial on using AES is VBScript: http://www.example-code.com/vbscript/AesIv.asp
The module mentioned in that tutorial can be found at: http://www.chilkatsoft.com/refdoc/xChilkatCrypt2Ref.html
回答4:
I know this question is old and OP disappeared, but it is worth noting for future vb6 users that VbCorLib now supports cryptography, including the dreaded Rijndael.
Link: http://vbcorlib.blogspot.com/
回答5:
One option would be to create a simple wrapper class in .NET for the RijndaelManaged class from the .NET framework and expose it via COM Interop so you can call it from VBScript.
回答6:
Here's my solution. It saves the the encryption key and initialization vector to a file so they can be reused.
Dim objAes, objAesEncryptor, objAesDecryptor, objUtf8Encoder Dim objStream, objFileSystem Dim strMyTextInUtf8, strMyEncyptedInUtf8, strMyText, strEncryptedInAnsi, strDecryptedInAnsi Dim strMyAesKeyFilename,strMyAesIvFilename Const adTypeBinary = 1 Const adSaveCreateOverWrite = 2 Const adSaveCreateNotExist = 1 ' https://stackoverflow.com/questions/270510/how-to-encrypt-in-vbscript-using-aes#28129895 Set objAes=WScript.CreateObject("System.Security.Cryptography.RijndaelManaged") Set objUtf8Encoder = CreateObject("System.Text.UTF8Encoding") strMyText = "This is a private message" strMyTextInUtf8=objUtf8Encoder.GetBytes_4(strMyText) strMyAesKeyFilename = "c:\Temp\objAes.Key" 'objAes.Key strMyAesIvFilename = "c:\Temp\objAes.IV" 'objAes.IV Set objFileSystem = CreateObject("Scripting.FileSystemObject") set objStream = createobject("Adodb.Stream") objStream.Type = adTypeBinary objStream.open If (objFileSystem.FileExists(strMyAesKeyFilename) And objFileSystem.FileExists(strMyAesKeyFilename)) Then objStream.LoadFromFile strMyAesKeyFilename objAes.Key = objStream.Read objStream.Close objStream.Open objStream.LoadFromFile strMyAesIvFilename objAes.IV = objStream.Read Else objAes.GenerateKey() objAes.GenerateIV() objStream.write objAes.Key objStream.savetofile strMyAesKeyFilename, adSaveCreateOverWrite objStream.Close objStream.open objStream.write objAes.IV objStream.savetofile strMyAesIvFilename, adSaveCreateOverWrite objStream.Close End IF Set objAesEncryptor = objAes.CreateEncryptor() Set objAesDecryptor = objAes.CreateDecryptor() strMyEncyptedInUtf8 = objAesEncryptor.TransformFinalBlock((strMyTextInUtf8),0,lenb(strMyTextInUtf8)) strEncryptedInAnsi = objUtf8Encoder.GetString((strMyEncyptedInUtf8)) WScript.Echo "Encrypted In Ansi: " & strEncryptedInAnsi strMyDecyptedInUtf8 = objAesDecryptor.TransformFinalBlock((strMyEncyptedInUtf8),0,lenb(strMyEncyptedInUtf8)) strDecryptedInAnsi = objUtf8Encoder.GetString((strMyDecyptedInUtf8)) WScript.Echo "Decrypted In Ansi: " & strDecryptedInAnsi
Running the script looks like this: