我正在使用带有CAPICOM
逻辑的VBS
程序集来加密某些text
,这很有效,但尝试使用Java
复制时会出现问题。
这是我的VBS代码:
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
通过调试上面的代码,我可以得到以下内容:
Hash
对象值为:
hash.Value = 636D0172D7FAC85AF9DB57FAE6C7D98B17DE5159
encryptedStr
的最终结果是:
encryptedStr = Y20Bctf6yFr521f65sfZixfeUVk=
所以,在Java
我试图复制相同的内容,我认为这可以通过...来完成...
获取SHA1
或String
的{{1}}哈希值(因为在InputStream
代码处有一个VBS
对象代表{{1} }})。
使用一些stm
方法(通过实现此方法,因为默认情况下Stream
中不存在此方法。)
使用HexToBinary
来自Java
哈希的二进制BASE64Encoder
。
最后,使用String
中的SHA1
方法(Left
代码的复制品),然后将org.apache.commons.lang.StringUtils
输出为VBS
{{1} }。
这就是我迄今为止在Java中尝试过至少生成encryptedStr
哈希(假设与base64
中的String
相同:
SHA1
以上代码将输出以下内容:
hash.Value
我在两种情况下使用相同的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;
}
}
和SHA1 from String is: 825CA9AF2795F3CCD41EC3B756CC7514E490842F
SHA1 from InputStream is: 825CA9AF2795F3CCD41EC3B756CC7514E490842F
)。
当我执行String
代码时,我从VBS
获取此Java
哈希值:
636D0172D7FAC85AF9DB57FAE6C7D98B17DE5159
当我执行VBS
代码时,我得到这个SHA1
哈希值:
825CA9AF2795F3CCD41EC3B756CC7514E490842F
如果CAPICOM
哈希值不相同,我将永远不会像Java
SHA1
那样得到base64
String
。
我做错了什么以及为什么encryptedStr
哈希在两种情况下的计算都不同。有人可以解释一下发生了什么或者实现这个的正确方法是什么,并在SHA1
得到相同的结果?
只是要知道,我发现这个链接有点帮助,并说他们可以得到相同的SHA1
,但不能解决我的问题:
http://us.generation-nt.com/answer/capicom-hasheddata-java-binary-files-help-44910362.html?page=2
如果有人想安装Java
并测试hash
代码,您可以执行以下操作:
- 将“capicom.dll”复制到“C:\ WINDOWS \ system32”
- 单击开始/程序/附件/命令提示符
- 输入“C:”
- 输入“cd C:\ WINDOWS \ system32”
- 输入“regsvr32.exe capicom.dll”
- 点击“确定”按钮。
- 输入“exit”
醇>
直接从CAPICOM
下载VBS
:
答案 0 :(得分:0)
表达String
的正确方法是使用这种方式:
String str = "Content-Type: plain/text; name=\"C:\\Users\\Luigi\\Desktop\\hello.txt\"" + "\r\n" +
"Content-Disposition: attachment; filename=\"C:\\Users\\Luigi\\Desktop\\hello.txt\"" + "\r\n" +
"test";
而不是\n
,我们需要使用\r\n
,然后SHA1
哈希将是相同的。
感谢Ansgar Wiechers揭露这一点。