1

I've been using the Java security api and was following the tutorial on how to generate digital signatures: http://docs.oracle.com/javase/tutorial/security/apisign/gensig.html

The problem is when I run the code, the output signature is always different even when the private key and data which is to be signed stays constant. I have provided the code below which I used to run. "priv" is a file which holds the private key and is used to sign the data: "hello".

Basically the two outputs show the same data: "hello" signed with the same key but it gives a different output. I was expecting the same output to be given. Also when I run the program again, the signed data is different again from the initial run. Any help would be much appreciated. Thanks in advance

public static void main(String[] args) {
   try {
      FileInputStream privfis;
      privfis = new FileInputStream("priv");
      byte[] encKey = new byte[privfis.available()];
      // obtain the encoded key in the file
      privfis.read(encKey);
      privfis.close();
      PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec( encKey);
      KeyFactory keyFactory = KeyFactory.getInstance("DSA", "SUN");
      PrivateKey priv = keyFactory.generatePrivate(privKeySpec);
      Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");
      dsa.initSign(priv);
      String message = "hello";
      System.out.println(getHexString(message.getBytes()));
      dsa.update(message.getBytes());
      byte[] realSig = dsa.sign();
      System.out.println(getHexString(realSig));
      dsa.update(message.getBytes()); 
      System.out.println(getHexString(message.getBytes()));
      byte[] realSig2 = dsa.sign();
      System.out.println(getHexString(realSig2));
      } catch (Exception e) {
         System.err.println("Caught exception " + e.toString());
         e.printStackTrace();
      }
   }

   private static String getHexString(byte[] b) {
      String result = "";
      for (int i = 0; i < b.length; i++) {
         result += Integer.toString((b[i] & 0xff) + 0x100, 16).substring(1);
      }
      return result;
   }        
}
Artjom B.
  • 61,146
  • 24
  • 125
  • 222
user1087943
  • 489
  • 1
  • 7
  • 15
  • In the documentation you cited, explicitly [here](http://docs.oracle.com/javase/tutorial/security/apisign/step2.html), it is mentioned that the key generator is using a RNG which needs to be seeded. – adrianp Apr 07 '13 at 18:29
  • [wikipedia Digital Signature Algorithm](https://en.wikipedia.org/wiki/Digital_Signature_Algorithm) explain the randomized per message k. – Aubin Apr 07 '13 at 18:32
  • @adrianp I've generated the key prior to the code I run in the original post. Therefore the signing private key is always the same – user1087943 Apr 07 '13 at 18:36
  • @user1087943 Then, what is the code you actually run? Because in the provided one you are generating a new key every time. – adrianp Apr 07 '13 at 18:37
  • @adrianp I run the code provided after I've saved the private/public key pair to file. I've checked the the code produces the same private key and it does. The code provided loads in the private key from storage using the fileinputstream and stores it in the private key variable. – user1087943 Apr 07 '13 at 18:44
  • @Aubin I had a read of the article. I kind of understand what's going on. So there's a random value (as in ElGamal) which alters the resulting signature everytime. In my code I don't put a random value in so is there a reason as to why there's a change in the resulting signature? – user1087943 Apr 07 '13 at 18:51
  • If the encoding was constant, it would be possible to imitate an exchange without knowing the keys (with recording). – Aubin Apr 07 '13 at 18:55
  • @Aubin Thanks for the swift reply. Is there a method of producing the same resulting signature through the DSA method of signing? – user1087943 Apr 07 '13 at 18:59

0 Answers0