JDK Tutorials - Herong's Tutorial Examples - Version 6.02, by Dr. Herong Yang
JcaSign.java - Signature Generation Sample Program
This section provides tutorial example on how to write a digital signature generation sample program to sign any input data with a given private key.
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) 2014, HerongYang.com, All Rights Reserved. */ 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.8 toString = java.security.KeyFactory@1db9742 Private Key Info: Algorithm = DSA Saved File = dsa.pri Length = 201 toString = sun.security.provider.DSAPrivateKey@29635 Signature Object Info: Algorithm = SHA1WithDSA Provider = SUN version 1.8 Sign Processing Info: Number of input bytes = 3116 Number of output bytes = 46
The program seems to be working:
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
Last update: 2014.
Table of Contents
Downloading and Installing JDK 1.8.0 on Windows
Downloading and Installing JDK 1.7.0 on Windows
Downloading and Installing JDK 1.6.2 on Windows
Date, Time and Calendar Classes
Date and Time Object and String Conversion
Number Object and Numeric String Conversion
Locales, Localization Methods and Resource Bundles
Calling and Importing Classes Defined in Unnamed Packages
HashSet, Vector, HashMap and Collection Classes
Character Set Encoding Classes and Methods
Encoding Conversion Programs for Encoded Text Files
Datagram Network Communication
DOM (Document Object Model) - API for XML Files
DTD (Document Type Definition) - XML Validation
XSD (XML Schema Definition) - XML Validation
XSL (Extensible Stylesheet Language)
Message Digest Algorithm Implementations in JDK
Private key and Public Key Pair Generation
PKCS#8/X.509 Private/Public Encoding Standards
►Digital Signature Algorithm and Sample Program
The Signing Process and the Verification Process
java.security.Signature - The Data Signing Class
JcaSignatureTest.java - Signature Test Program
►JcaSign.java - Signature Generation Sample Program
JcaVerify.java - Signature Verification Sample Program
"keytool" Commands and "keystore" Files
KeyStore and Certificate Classes
Secret Key Generation and Management
Cipher - Secret Key Encryption and Decryption
The SSL (Secure Socket Layer) Protocol
SSL Socket Communication Testing Programs