1

我正在使用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我试图复制相同的内容时,我认为这可以通过......

  1. 获取orSHA1的散列(因为在代码中有一个代表 a 的对象)。StringInputStreamVBSstmStream

  2. 使用一些HexToBinary方法(通过实现这个,因为默认情况下这个方法在 中不存在Java)。

  3. 用于哈希BASE64Encoder的二进制文件StringSHA1

  4. 最后,使用Left方法 from org.apache.commons.lang.StringUtils(复制VBS代码),然后输出encryptedStrbase64 String.

到目前为止,这是我在 Java 中尝试过的至少生成哈希的方法(假设与SHA1以下内容相同:hash.ValueVBS

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在两种情况下都使用相同的加密(VBSJava)。

  • 当我执行VBS代码时,我SHA1从以下位置获取此哈希值CAPICOM

    636D0172D7FAC85AF9DB57FAE6C7D98B17DE5159

  • 当我执行Java代码时,我得到了这个SHA1哈希值:

    825CA9AF2795F3CCD41EC3B756CC7514E490842F

  • 如果哈希不一样base64 String,我永远不会得到相同的结果。encryptedStrSHA1


我的问题:

我做错了什么以及为什么SHA1哈希在两种情况下的计算方式都不同。有人可以解释正在发生的事情或实现这一点并获得相同结果的正确方法是什么Java吗?

只是要知道,我发现这个链接有点帮助,并说他们可以得到相同的结果hash,但不能解决我的问题:

http://us.generation-nt.com/answer/capicom-hasheddata-java-binary-files-help-44910362.html?page=2

如果有人想安装CAPICOM和测试VBS代码,您可以执行以下操作:

  1. 将“capicom.dll”复制到“C:\WINDOWS\system32”
  2. 单击开始/程序/附件/命令提示符
  3. 键入“C:”
  4. 键入“cd C:\WINDOWS\system32”
  5. 键入“regsvr32.exe capicom.dll”
  6. 单击“确定”按钮。
  7. 输入“退出”

capicom.dll并直接从以下位置下载自己Microsoft

http://www.microsoft.com/downloads/details.aspx?FamilyID=860EE43A-A843-462F-ABB5-FF88EA5896F6&displaylang=en

4

1 回答 1

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 揭露这一点。

于 2013-05-16T20:54:04.480 回答