signature.verify 是 returns 错误

signature.verify is returns false

我正在学习 Java 中的签名,我从 java 文档中获得了代码,但它似乎不起作用。谁能告诉我我做错了什么。任何帮助将不胜感激。

第一部分是创建签名,第二部分是检查签名

import java.io.*;
import java.security.*;
import java.security.spec.*;

public class SignatureVerification {
   public static void main(String args[]) throws Exception{
      
      KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA","SUN");
      
      SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
        keyGen.initialize(1024, random);
      //Generate the pair of keys
      KeyPair pair = keyGen.generateKeyPair();
      PrivateKey priv = pair.getPrivate();
      PublicKey pub = pair.getPublic();


      //Creating a Signature object
      Signature dsa = Signature.getInstance("SHA256withDSA","SUN");
      
      dsa.initSign(priv);
      
      FileInputStream fis = new FileInputStream("Cust.ser");
        BufferedInputStream bufin = new BufferedInputStream(fis);
        byte[] buffer = new byte[1024];
        int len;
        while ((len = bufin.read(buffer)) >= 0) {
            dsa.update(buffer, 0, len);
        };
        bufin.close();
      
      byte[] realSig = dsa.sign();
      
        
        byte[] key = pub.getEncoded();


        // /////////////////////////////////////////////////////////////////

            X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(key);
            KeyFactory keyFactory = KeyFactory.getInstance("DSA","SUN");
            PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);


            Signature sig = Signature.getInstance("SHA256withDSA","SUN");
            sig.initVerify(pubKey);

            FileInputStream datafis = new FileInputStream("Cust.ser");
            BufferedInputStream bufin2 = new BufferedInputStream(datafis);

            byte[] buffer2 = new byte[1024];
            int len2;
            while (bufin2.available() != 0) {
                len2 = bufin2.read(buffer);
                sig.update(buffer2, 0, len2);
            };

            bufin2.close();

            System.out.println(realSig);
            System.out.println(sig);


            boolean verifies = sig.verify(realSig);

            System.out.println("signature verifies: " + verifies);


   }
}

cmd输出结果如下

java SignatureVerification
[B@5cad8086
Signature object: SHA256withDSA<initialized for verifying>
signature verifies: false

当您剪切和粘贴代码时,您没有正确编辑。它仍然 读取 数据到 buffer,但它不 使用 该数据,而是使用 buffer2 (全为零):

            byte[] buffer2 = new byte[1024];
            int len2;
            while (bufin2.available() != 0) {
                len2 = bufin2.read(buffer);
                sig.update(buffer2, 0, len2);
            };

此外,通常 available() 可以 return 0 即使文件中有更多数据,所以这不可靠;你在签名部分使用的方法,while( (len=inputstream.read(buffer))>=0 ) 好多了。

如果您不知道,1024 位 DSA 虽然(还)没有真正被破坏,但不再被认为是安全的,并且不再允许在需要安全性的地方使用,尤其是不与 SHA 结合使用时- 256. Java 自 2014 年 j8 以来的加密支持符合 FIPS 186-3 的 SHA-2 的 2048 位和 3072 位 DSA。