|
JCA - Digital Signature
Part:
1
2
3
4
5
(Continued from previous part...)
Signature Generation Program - JcaSign.java
The following program is a standalone program that reads in an input file and a private
key file, and generates a signature file based on the specified digital signature algorithm.
/**
* JcaSign.java
* Copyright (c) 2002 by Dr. Herong Yang
*/
import java.io.*;
import java.security.*;
import java.security.spec.*;
class JcaSign {
public static void main(String[] a) {
if (a.length<5) {
System.out.println("Usage:");
System.out.println("java JcaSign 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 {
PrivateKey priKey = readPrivateKey(keyFile,keyAlgo);
sign(input,signFile,signAlgo,priKey);
} catch (Exception e) {
System.out.println("Exception: "+e);
return;
}
}
private static PrivateKey readPrivateKey(String input,
String algorithm) throws Exception {
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
System.out.println();
System.out.println("KeyFactory Object Info: ");
System.out.println("Algorithm = "+keyFactory.getAlgorithm());
System.out.println("Provider = "+keyFactory.getProvider());
System.out.println("toString = "+keyFactory.toString());
FileInputStream priKeyStream = new FileInputStream(input);
int priKeyLength = priKeyStream.available();
byte[] priKeyBytes = new byte[priKeyLength];
priKeyStream.read(priKeyBytes);
priKeyStream.close();
PKCS8EncodedKeySpec priKeySpec
= new PKCS8EncodedKeySpec(priKeyBytes);
PrivateKey priKey = keyFactory.generatePrivate(priKeySpec);
System.out.println();
System.out.println("Private Key Info: ");
System.out.println("Algorithm = "+priKey.getAlgorithm());
System.out.println("Saved File = "+input);
System.out.println("Length = "+priKeyBytes.length);
System.out.println("toString = "+priKey.toString());
return priKey;
}
private static byte[] sign(String input, String output,
String algorithm, PrivateKey priKey) throws Exception {
Signature sg = Signature.getInstance(algorithm);
sg.initSign(priKey);
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();
FileOutputStream out = new FileOutputStream(output);
byte[] sign = sg.sign();
out.write(sign);
out.close();
System.out.println();
System.out.println("Sign Processing Info: ");
System.out.println("Number of input bytes = "+count);
System.out.println("Number of output bytes = "+sign.length);
return sign;
}
}
As you can see, this program also uses the KeyFactory class to read in the private key
stored in an encoded file, which can be generated by my other program, JcaKeyPair.java.
Here is result of my first test using DSA as the key generation algorithm,
and SHA1withDSA as the digital signature algorithm. It is done with JDK 1.3.1.
java -cp . JcaKeyPair 512 dsa DSA
java -cp . JcaSign JcaSign.class JcaSign_dsa.sgn SHA1withDSA dsa.pri DSA
KeyFactory Object Info:
Algorithm = DSA
Provider = SUN version 1.2
toString = java.security.KeyFactory@53c015
Private Key Info:
Algorithm = DSA
Saved File = dsa.pri
Length = 201
toString = Sun DSA Private 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
x: 4bf261ad9e69a12993a48f63b43b81c61f2aebfd
Signature Object Info:
Algorithm = SHA/DSA
Provider = SUN version 1.2
Sign Processing Info:
Number of input bytes = 2940
Number of output bytes = 46
The program seems to be working:
- A pair of keys is generated using the DSA algorithm first. The private key is stored in
dsa.pri, and the public key in dsa.pub.
- The private key is decoded from the file using the KeyFactory class in PKCS#8 format.
- Then a signature is generated for input file, JcaSign.class, using
the SHA1withDSA algorithm, which uses SHA-1 for the message digest generation, and
DSA for encryption.
- The signature is stored in JcaSign_dsa.sgn.
Now try it with the RSA key generation algorithm. You should have no problem at all.
java -cp . JcaKeyPair 512 rsa RSA
java -cp . JcaSign JcaSign.class JcaSign_rsa.sgn MD2withRSA rsa.pri RSA
(Continued on next part...)
Part:
1
2
3
4
5
|