Create Digital Signature
1 Generate public-private key :
Instantiate and initialize key-pair generator to generate keys
2. Digitally sign the file with private key:
Instantiate and initialize Signature to update the given file with signature generated
3. Persist the sign and public key:
save the signed file and public key
public class CreateDigitalSignature {
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException, SignatureException, IOException {
// 1. Generate public-private key
Map<String, Key> keys = generateKeys();
// 2. Digitally sign the file with private key
byte[] sign = sign(keys.get("privateKey"));
// 3. Persist the sign and public key
saveSignAndPublicKey(keys.get("publicKey"), sign);
}
/**
* The method generate public-private key.
* This involved 3 steps, Instantiate, initialize and create
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
*/
private static Map<String, Key> generateKeys() throws NoSuchAlgorithmException, NoSuchProviderException {
Map<String, Key> keys = new HashMap<>();
/**
* Instantiate key-pair generator object using KeyPairGenerator
* getInstance has two form: String algorithm or provider(this guarantee that the implementation of an algorithm)
*/
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
/**
* Keysize for a DSA key generator is the key length (in bits)
* Instance of SecureRandom that uses the SHA1PRNG algorithm, as provided by the built-in SUN provide
*/
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(1024, random);
/**
* Generate private & public key
*/
KeyPair keyPair = keyGen.generateKeyPair();
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
keys.put("privateKey", privateKey);
keys.put("publicKey", publicKey);
System.out.println("Key is generated");
return keys;
}
/**
* Method sign file with private key generated
* @param key
* @return
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws InvalidKeyException
* @throws SignatureException
* @throws IOException
*/
private static byte[] sign(Key key) throws NoSuchAlgorithmException, NoSuchProviderException,
InvalidKeyException, SignatureException, IOException {
/**
* Instantiate and initiate the Signature class
*/
Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");
dsa.initSign((PrivateKey) key);
/**
* Read in the data a buffer at a time and will supply it to the Signature object by calling the update method
*/
byte[] buffer = new byte[1024];
int len;
try (BufferedInputStream br = new BufferedInputStream(new FileInputStream("D:\\Demandware\\digitalSignature\\Name.txt"))) {
while ((len = br.read(buffer)) >= 0) {
dsa.update(buffer, 0, len);
}
}
/**
* Generate the Signature
*/
byte[] realSig = dsa.sign();
return realSig;
}
/**
* Method save the Signature and the Public Key in Files
* @param key
* @param signedFileInByte
* @throws IOException
*/
private static void saveSignAndPublicKey(Key key, byte[] signedFileInByte) throws IOException {
/**
* Save the sign in a file
*/
try (FileOutputStream savedSign = new FileOutputStream("D:\\Demandware\\digitalSignature\\mysign")) {
savedSign.write(signedFileInByte);
}
/**
* Save the public key
*/
byte[] publickey = key.getEncoded();
try (FileOutputStream keyfos = new FileOutputStream("D:\\Demandware\\digitalSignature\\mypublickey")) {
keyfos.write(publickey);
}
}
}
Verification of digitally signed file
1. Get the public key
Read the file used to store public key and store in an byte array. Using the keyStore get public key
2. Get the signature
Read the signature file and get the sign
3. Verify the file with public key and signature
Open the requeted file and verify signature against signature
public class VerifySignature {
public static void main(String[] args) throws FileNotFoundException, IOException, NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeySpecException, InvalidKeyException, SignatureException {
// Get the public key
PublicKey publickey = getPublicKey();
// get the signature
byte[] sign2Verify = getSignature2Verify();
// verify the file with public key and signature
verifySignature(publickey, sign2Verify);
}
/**
* Generate the public key
*
* @return
* @throws IOException
* @throws FileNotFoundException
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws InvalidKeySpecException
*/
private static PublicKey getPublicKey() throws IOException, FileNotFoundException, NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeySpecException {
/**
* Read the file used to store public key and store in an byte array
*/
byte[] encKey = null;
try (FileInputStream keyFile = new FileInputStream("D:\\Demandware\\digitalSignature\\mypublickey")) {
encKey = new byte[keyFile.available()];
keyFile.read(encKey);
}
/**
* Key specification required-assuming that the key was encoded
* according to the X.509 standard-(built-in DSA key-pair generator
* supplied by the SUN provider)
*/
X509EncodedKeySpec pubKeySpec = null;
if (encKey != null) {
pubKeySpec = new X509EncodedKeySpec(encKey);
}
/**
* KeyFactory class in order to instantiate a DSA public key from its
* encoding
*/
KeyFactory keyFactory = KeyFactory.getInstance("DSA", "SUN");
/**
* KeyFactory object to generate a PublicKey from the key specification
*/
PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);
return pubKey;
}
/**
* Method return the signature after reading the file
* @return
* @throws FileNotFoundException
* @throws IOException
*/
private static byte[] getSignature2Verify() throws FileNotFoundException, IOException {
byte[] sign2Verify = null;
try (FileInputStream signFile = new FileInputStream("D:\\Demandware\\digitalSignature\\mysign")) {
sign2Verify = new byte[signFile.available()];
signFile.read(sign2Verify);
}
return sign2Verify;
}
/**
* Method to verify signature
* @param pubKey
* @param sign2Verify
* @throws NoSuchAlgorithmException
* @throws NoSuchProviderException
* @throws InvalidKeyException
* @throws SignatureException
* @throws IOException
*/
private static void verifySignature(PublicKey pubKey, byte[] sign2Verify) throws NoSuchAlgorithmException,
NoSuchProviderException, InvalidKeyException, SignatureException, IOException {
/**
* Signature object that uses the same signature algorithm as was used to generate the signature
*/
Signature sig = Signature.getInstance("SHA1withDSA", "SUN");
/**
* initialize the Signature object
*/
sig.initVerify(pubKey);
/**
* Read in the data a buffer at a time and will supply it to the
* Signature object by calling the update method
*/
byte[] buffer = new byte[1024];
int len;
try (BufferedInputStream br = new BufferedInputStream(
new FileInputStream("D:\\Demandware\\digitalSignature\\Name.txt"))) {
while ((len = br.read(buffer)) >= 0) {
sig.update(buffer, 0, len);
}
}
/**
* Verify the signature
*/
boolean verifies = sig.verify(sign2Verify);
System.out.println("signature verifies: " + verifies);
}
}