Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
98 views
in Technique[技术] by (71.8m points)

java - signature.verify is returns false

I am learning signatures in Java, I got the code from java documentation but it does not seem to work. Can anyone please tell me what I have done wrong. Any help would be appreciated.

The first part is creating the signature, the second part is checking the signature

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);


   }
}

The cmd output shows as follows

java SignatureVerification
[B@5cad8086
Signature object: SHA256withDSA<initialized for verifying>
signature verifies: false
question from:https://stackoverflow.com/questions/66057155/signature-verify-is-returns-false

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

When you cut&pasted your code, you didn't edit correctly. It still reads the data into buffer, but it doesn't use that data, instead it uses buffer2 (which is all zeros):

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

Also, in general available() can return 0 even when there is more data in the file, so this isn't reliable; the method you used in the signing part, while( (len=inputstream.read(buffer))>=0 ) is much better.

And in case you aren't aware, 1024-bit DSA, although not actually broken (yet), is no longer considered safe and no longer allowed for use where security is needed, especially not in conjunction with SHA-256. Java crypto since j8 in 2014 supports 2048-bit and 3072-bit DSA with SHA-2 as per FIPS 186-3.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...