|
JCA - Digital Signature
Part:
1
2
3
4
5
(Continued from previous part...)
Signature Verification Program - JcaVerify.java
The following program is a standalone program that reads in an input file, a signature file
and a public key file, and verifies that if the signature file matches the input file
based on the specified digital signature algorithm.
/**
* JcaVerify.java
* Copyright (c) 2002 by Dr. Herong Yang
*/
import java.io.*;
import java.security.*;
import java.security.spec.*;
class JcaVerify {
public static void main(String[] a) {
if (a.length<5) {
System.out.println("Usage:");
System.out.println("java JcaVerify input signFile"
+" signAlgo keyFile keyAlgo");
return;
}
String input = a[0];
String signFile = a[1];
String signAlgo = a[2]; // SHA1withDSA, SHA1withRSA,
String keyFile = a[3];
String keyAlgo = a[4]; // DSA, RSA
try {
PublicKey pubKey = readPublicKey(keyFile,keyAlgo);
byte[] sign = readSignature(signFile);
verify(input,signAlgo,sign,pubKey);
} catch (Exception e) {
System.out.println("Exception: "+e);
return;
}
}
private static PublicKey readPublicKey(String input,
String algorithm) throws Exception {
FileInputStream pubKeyStream = new FileInputStream(input);
int pubKeyLength = pubKeyStream.available();
byte[] pubKeyBytes = new byte[pubKeyLength];
pubKeyStream.read(pubKeyBytes);
pubKeyStream.close();
X509EncodedKeySpec pubKeySpec
= new X509EncodedKeySpec(pubKeyBytes);
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
System.out.println();
System.out.println("Public Key Info: ");
System.out.println("Algorithm = "+pubKey.getAlgorithm());
System.out.println("Saved File = "+input);
System.out.println("Length = "+pubKeyBytes.length);
System.out.println("toString = "+pubKey.toString());
return pubKey;
}
private static byte[] readSignature(String input)
throws Exception {
FileInputStream signStream = new FileInputStream(input);
int signLength = signStream.available();
byte[] signBytes = new byte[signLength];
signStream.read(signBytes);
signStream.close();
return signBytes;
}
private static boolean verify(String input, String algorithm,
byte[] sign, PublicKey pubKey) throws Exception {
Signature sg = Signature.getInstance(algorithm);
sg.initVerify(pubKey);
System.out.println();
System.out.println("Signature Object Info: ");
System.out.println("Algorithm = "+sg.getAlgorithm());
System.out.println("Provider = "+sg.getProvider());
FileInputStream in = new FileInputStream(input);
int bufSize = 1024;
byte[] buffer = new byte[bufSize];
int n = in.read(buffer,0,bufSize);
int count = 0;
while (n!=-1) {
count += n;
sg.update(buffer,0,n);
n = in.read(buffer,0,bufSize);
}
in.close();
boolean ok = sg.verify(sign);
System.out.println("Verify Processing Info: ");
System.out.println("Number of input bytes = "+count);
System.out.println("Verification result = "+ok);
return ok;
}
}
Here is result of my first test to verify a signature generated with the DSA algorithm
and the SHA1withDSA algorithm. See the previous section for more information.
java -cp . JcaVerify JcaSign.class JcaSign.sgn SHA1withDSA dsa.pub DSA
Public Key Info:
Algorithm = DSA
Saved File = dsa.pub
Length = 243
toString = Sun DSA Public Key
Parameters:DSA
p:
fca682ce 8e12caba 26efccf7 110e526d b078b05e decbcd1e b4a208f3 ae1617ae
01f35b91 a47e6df6 3413c5e1 2ed0899b cd132acd 50d99151 bdc43ee7 37592e17
q:
962eddcc 369cba8e bb260ee6 b6a126d9 346e38c5
g:
678471b2 7a9cf44e e91a49c5 147db1a9 aaf244f0 5a434d64 86931d2d 14271b9e
35030b71 fd73da17 9069b32e 2935630e 1c206235 4d0da20a 6c416e50 be794ca4
y:
2cf7c9ba a2dd3ce5 0e2d6384 122951fa a956ebd9 573a5168 ce9c0a83 b8c63348
ce5c5d65 b35c8c81 beb9206b 8cf36587 0b24e605 a0150dbe a40dd57d 64b42b8a
Signature Object Info:
Algorithm = SHA/DSA
Provider = SUN version 1.2
Verify Processing Info:
Number of input bytes = 2940
Verification result = true
Yes. The program is working correctly. Here is another on the signature generated
with RSA and MD2withRSA algorithms.
java -cp . JcaVerify JcaSign.class JcaSign_rsa.sgn MD2withRSA rsa.pub RSA
Public Key Info:
Algorithm = RSA
Saved File = rsa.pub
Length = 94
toString = com.sun.rsajca.JSA_RSAPublicKey@12e78c
Signature Object Info:
Algorithm = MD2withRSA
Provider = SunRsaSign version 1.0
Verify Processing Info:
Number of input bytes = 2940
Verification result = true
Conclusions:
- Generating and verification digital signatures are done by encrypting and decrypting
the message digest of the input data with private keys and public keys.
- The Signature class requires the help of the KeyPairGenerator class and the KeyFactory
class.
- Sun provides several digital signature algorithms: SHA1withDSA, SHA1withRSA,
MD2withDSA, and MD2withRSA.
- Of course, you must choose a digital signature algorithm that is compatible with
the keys.
- Keys are stored in files in encoded formats. The default encoding for private key is
PKCS#8, and the default encoding for public key is X.509.
Part:
1
2
3
4
5
|