I am using CAPICOM
assembly with VBS
logic to encrypt some text
, this works good but the problem starts when trying to replicate the same using Java
.
This is my VBS code:
Option Explicit
Dim strToEncrypt: strToEncrypt = "Content-Type: plain/text; name=""C:\Users\Luigi\Desktop\hello.txt""" & vbCrLf & _
"Content-Disposition: attachment; filename=""C:\Users\Luigi\Desktop\hello.txt""" & vbCrLf & _
"test"
Dim encryptedStr: encryptedStr = CRYPTO_SHA1(strToEncrypt)
WScript.Echo encryptedStr
Private Function CRYPTO_SHA1(strData) 'As String
Const CAPICOM_HASH_ALGORITHM_SHA1 = 0
Dim hash: Set hash = CreateObject("CAPICOM.HashedData")
Dim util: Set util = CreateObject("CAPICOM.Utilities")
Dim stm: Set stm = CreateObject("ADODB.Stream")
stm.Open
stm.Type = 2 'adTypeText
stm.Charset = "us-ascii"
stm.WriteText strData
stm.Position = 0
stm.Type = 1 'adTypeBinary
hash.Algorithm = CAPICOM_HASH_ALGORITHM_SHA1
hash.Hash stm.Read
CRYPTO_SHA1 = util.Base64Encode(util.HexToBinary(hash.Value))
CRYPTO_SHA1 = Left(CRYPTO_SHA1, Len(CRYPTO_SHA1)-Len(vbCrLf))
stm.Close
Set stm = Nothing
Set util = Nothing
Set hash = Nothing
End Function
By debugging the above code, I can get the following:
Hash
object value is:
hash.Value = 636D0172D7FAC85AF9DB57FAE6C7D98B17DE5159
The final result as encryptedStr
is:
encryptedStr = Y20Bctf6yFr521f65sfZixfeUVk=
So, in Java
I am trying to replicate the same and I assume this can be done by...
Getting
SHA1
hash of theString
orInputStream
(because atVBS
code there is anstm
object that represents aStream
).Use some
HexToBinary
method (by implementing this because by default this method doesn't exist inJava
).Use
BASE64Encoder
for the binaryString
fromSHA1
hash.Finally, use
Left
method fromorg.apache.commons.lang.StringUtils
(replicate of theVBS
code) and then outputencryptedStr
asbase64
String
.
This is what I've tried so far in Java to at least generate the SHA1
hash (supposed to be the same as hash.Value
in VBS
:
package my.package;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.DigestInputStream;
import java.security.MessageDigest;
public class SHA1Encrypt {
public static void main(String[] args) throws Exception {
String str = "Content-Type: plain/text; name=\"C:\\Users\\Luigi\\Desktop\\hello.txt\"" + "\n" +
"Content-Disposition: attachment; filename=\"C:\\Users\\Luigi\\Desktop\\hello.txt\"" + "\n" +
"test";
String SHA1FromString = getSHA1FromString(str);
String SHA1FromIS = getSHA1FromIS(str);
System.out.println("SHA1 from String is: " + SHA1FromString.toUpperCase());
System.out.println("SHA1 from InputStream is: " + SHA1FromIS.toUpperCase());
}
public static String getSHA1FromString(String str) throws Exception {
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
sha1.update(str.getBytes());
byte[] digest = sha1.digest();
return byteArrayToHexString(digest);
}
public static String getSHA1FromIS(String str) throws Exception{
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
InputStream is = new ByteArrayInputStream(str.getBytes());
BufferedInputStream bis = new BufferedInputStream(is);
DigestInputStream dis = new DigestInputStream(bis, sha1);
while (dis.read() != -1);
byte[] digest = sha1.digest();
return byteArrayToHexString(digest);
}
public static String byteArrayToHexString(byte[] b) {
String result = "";
for (int i=0; i < b.length; i++) {
result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
}
return result;
}
}
The above code will output the following:
SHA1 from String is: 825CA9AF2795F3CCD41EC3B756CC7514E490842F
SHA1 from InputStream is: 825CA9AF2795F3CCD41EC3B756CC7514E490842F
The problem:
I am using the same
String
to be encrypted in both cases (VBS
andJava
).When I execute
VBS
code I get thisSHA1
hash value fromCAPICOM
:636D0172D7FAC85AF9DB57FAE6C7D98B17DE5159
When I execute
Java
code I get thisSHA1
hash value:825CA9AF2795F3CCD41EC3B756CC7514E490842F
I won't never get the same
base64
String
asencryptedStr
ifSHA1
hash is not the same.
My Question:
What I am doing wrong and why did SHA1
hash gets computed different in both cases. Can someone please explain what is happening or what is the correct way to implement this and get the same result in Java
?
Just to know, I found this link that helps a little and says that they can get the same hash
but doesn't fix the problem for my case:
http://us.generation-nt.com/answer/capicom-hasheddata-java-binary-files-help-44910362.html?page=2
If someone wants to install CAPICOM
and test VBS
code, you can do the following:
- Copy "capicom.dll" to "C:\WINDOWS\system32"
- Click on Start/Programs/Accessories/Command Prompt
- Type "C:"
- Type "cd C:\WINDOWS\system32"
- Type "regsvr32.exe capicom.dll"
- Click on the "OK" button.
- Type "exit"
And download the capicom.dll
yourself directly from Microsoft
at: