0

我正在实现一个将 3 件事作为输入的接口

  1. X509证书

  2. 使用该证书的私钥签名的 signedHash

  3. 初始哈希

它必须执行以下操作:

  1. 确认此哈希是使用提供的证书签名的。
  2. 使用作为输入提供的证书的公钥解密签名的哈希,并检查它是否与提供的哈希匹配。

我已经实现了以下验证数字签名:-

 public static boolean verifySignedHash(String X509Certificate, String hash,
            String signedHash) {

        boolean isVerified = false;

        ByteArrayInputStream inputStream = null;
        ByteArrayOutputStream outputStream = null;
        ByteArrayOutputStream byo = null;


        try {

            outputStream = new ByteArrayOutputStream();

            byte[] data = Base64.decodeBase64(X509Certificate);

            /* writing decoded X509 certificate to the ByteArrayOutputStream */

            outputStream.write(data);

            byte[] inp = outputStream.toByteArray();
            inputStream = new ByteArrayInputStream(inp);

            /* Getting the certificate from the Input */

            CertificateFactory cf = CertificateFactory.getInstance("X.509");

            X509Certificate certs = (X509Certificate) cf
                    .generateCertificate(inputStream);

            /* import encoded public key */

            X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(certs
                    .getPublicKey().getEncoded());

            /* Instantiating KeyFactory for accesing the Keys as Object */

            KeyFactory keyFactory = KeyFactory.getInstance("RSA");

            /*
             * using the KeyFactory object to generate a PublicKey from the key
             * specification.
             */

            publickKey = keyFactory.generatePublic(pubKeySpec);

            byte[] signHash = Base64.decodeBase64(signedHash);

            byo = new ByteArrayOutputStream();

            byo.write(signHash);

            byte[] signChar = byo.toByteArray();

            ByteArrayInputStream byi = new ByteArrayInputStream(signChar);

            /* Next, input the signature bytes from the file specified */

            byte[] sigToVerify = new byte[byi.available()];
            byi.read(sigToVerify);
            byi.close();

            /* Instantiating Signature */
            Signature signature = Signature.getInstance(certs.getSigAlgName());

            /* Initializing the Public Key in Signature */

            signature.initVerify(publickKey);

            /* Supply the Signature Object With the Data to be Verified */

            BufferedInputStream bufin = new BufferedInputStream(byi);

            byte[] buffer = new byte[1024];
            int len;
            while (bufin.available() != 0) {
                len = bufin.read(buffer);
                signature.update(buffer, 0, len);
            };

            bufin.close();

            /* Verify the Signature */

            isVerified = signature.verify(sigToVerify);

        } catch (Exception e) {
            System.err.println("Caught exception " + e.toString());
        }

        return isVerified;
    }

我得到的结果为 False

**Am i Missing something or is this piece of code correct ?**

我真的很感谢你的帮助。非常感谢。

4

1 回答 1

1

我复制了原始代码并将我的评论放在代码中

// X509Certificate is class name, it cannot be variable name
public static boolean verifySignedHash(String X509Certificate, String hash,
        String signedHash) {

    // Java is not C89 you don't have to declare variables in the beginning
    // of function, this reduces readability of the code and allows misuse
    boolean isVerified = false;

    ByteArrayInputStream inputStream = null;
    ByteArrayOutputStream outputStream = null;
    ByteArrayOutputStream byo = null;

    try {

        outputStream = new ByteArrayOutputStream();

        byte[] data = Base64.decodeBase64(X509Certificate);

        /* writing decoded X509 certificate to the ByteArrayOutputStream */

        outputStream.write(data);

        byte[] inp = outputStream.toByteArray();

        // at this point inp is the same array as data, this makes no sence
        // and reduce performance

        inputStream = new ByteArrayInputStream(inp);

        /* Getting the certificate from the Input */

        CertificateFactory cf = CertificateFactory.getInstance("X.509");

        X509Certificate certs = (X509Certificate) cf
                .generateCertificate(inputStream);

        /* import encoded public key */
        // certs.getPublicKey() returns publicKey immediately, why to do
        // all these conversions?

        X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(certs
                .getPublicKey().getEncoded());

        /* Instantiating KeyFactory for accesing the Keys as Object */

        KeyFactory keyFactory = KeyFactory.getInstance("RSA");

        /*
         * using the KeyFactory object to generate a PublicKey from the key
         * specification.
         */

        publickKey = keyFactory.generatePublic(pubKeySpec);

        byte[] signHash = Base64.decodeBase64(signedHash);

        byo = new ByteArrayOutputStream();

        byo.write(signHash);

        byte[] signChar = byo.toByteArray();

        // Again, signChar is the same as signHash, why would you do that?

        ByteArrayInputStream byi = new ByteArrayInputStream(signChar);

        /* Next, input the signature bytes from the file specified */

        byte[] sigToVerify = new byte[byi.available()];
        byi.read(sigToVerify);
        byi.close();

        // And now sigToVerify is the same as signChar and signHash.

        /* Instantiating Signature */
        Signature signature = Signature.getInstance(certs.getSigAlgName());

        /* Initializing the Public Key in Signature */

        signature.initVerify(publickKey);

        /* Supply the Signature Object With the Data to be Verified */

        // byi is already closed, you will get java.io.IOException: Stream closed
        BufferedInputStream bufin = new BufferedInputStream(byi);

        byte[] buffer = new byte[1024];
        int len;
        while (bufin.available() != 0) {
            len = bufin.read(buffer);
            signature.update(buffer, 0, len);
            // Any way bufin contained signature, while you need feed
            // plaintext to signature.update()
            // I could assume unused parameter hash has something to do
            // with plaintext
        };

        bufin.close();

        /* Verify the Signature */

        isVerified = signature.verify(sigToVerify);

    } catch (Exception e) {
        System.err.println("Caught exception " + e.toString());
    }

    return isVerified;
}
于 2014-10-15T12:48:49.487 回答