package elte.java2_utikalauz5.crypto; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.security.KeyStore; import java.security.Signature; import java.security.KeyStore.PrivateKeyEntry; import java.security.KeyStore.TrustedCertificateEntry; /** Digitális aláírás. @link.forrásfájl {@docRoot}/../data/crypto/src Sign.java @link.letöltés {@docRoot}/../data/crypto Sign.jar @since Java 2 Útikalauz programozóknak 5.0 */ public class Sign { private final File inFile; private final File signatureFile; private final KeyStore.PrivateKeyEntry dsaKeyPair; private final KeyStore.TrustedCertificateEntry dsaCertificate; private final boolean isSign; public Sign(boolean isSign, String keyId, String keyStore, String keyPassword, String keyStorePassword, String inFileName, String sigFileName) throws Exception { this.isSign = isSign; this.inFile = new File(inFileName); this.signatureFile = new File(sigFileName); KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(new FileInputStream(keyStore), keyStorePassword.toCharArray()); KeyStore.PasswordProtection keyPwd = new KeyStore.PasswordProtection(keyPassword.toCharArray()); if( this.isSign ) { this.dsaKeyPair = (PrivateKeyEntry) ks.getEntry(keyId, keyPwd); this.dsaCertificate = null; } else { this.dsaKeyPair = null; this.dsaCertificate = (TrustedCertificateEntry) ks.getEntry(keyId, keyPwd); } } public void execute() throws Exception { if( this.isSign ) { sign(); } else { verify(); } } private void sign() throws Exception { Signature signer = Signature.getInstance("DSA"); signer.initSign(this.dsaKeyPair.getPrivateKey()); processInput(signer); FileOutputStream sigFile = null; try { sigFile = new FileOutputStream(this.signatureFile); sigFile.write(signer.sign()); } finally { if( null != sigFile ) { sigFile.close(); } } } private void processInput(Signature signature) throws Exception { FileInputStream fis = null; try { fis = new FileInputStream(this.inFile); byte[] buffer = new byte[2048]; int len; while( (len = fis.read(buffer)) >= 0 ) { signature.update(buffer,0,len); } } finally { if( null != fis ) { fis.close(); } } } private void verify() throws Exception { Signature verifier = Signature.getInstance("DSA"); verifier.initVerify(this.dsaKeyPair.getCertificate()); processInput(verifier); FileInputStream sigFile = null; try { sigFile = new FileInputStream(this.signatureFile); int length = sigFile.available(); byte[] signature = new byte[length]; if( length != sigFile.read(signature) ) { throw new IOException("Unexpected end of file!"); } if( verifier.verify(signature) ) { System.out.println("The signature is valid"); } else { System.out.println("The signature is invalid"); } } finally { if( null != sigFile ) { sigFile.close(); } } } /** * @param args * @throws Exception */ public static void main(String[] args) throws Exception { Sign signer = parseArgs(args); signer.execute(); } private static final String KEYID_SWITCH = "--keyid:"; private static final String KEYSTORE_SWITCH = "--keystore:"; private static final String KEYPASSWORD_SWITCH = "--keypassword:"; private static final String KEYSTOREPASSWORD_SWITCH = "--keystorepassword:"; private static final String VERIFY_SWITCH = "--verify"; private static Sign parseArgs(String[] args) throws Exception { String keyId = null; String inFileName = null; String sigFileName = null; String keyPassword = null; String keyStorePassword = null; String keyStore = ".keystore"; boolean isSign = true; for( String arg: args ) { if( arg.startsWith("-")) { if( arg.startsWith(KEYID_SWITCH)) { keyId = arg.substring(KEYID_SWITCH.length()); } else if( arg.startsWith(KEYSTORE_SWITCH)) { keyStore = arg.substring(KEYSTORE_SWITCH.length()); } else if( arg.startsWith(KEYSTOREPASSWORD_SWITCH)) { keyStorePassword = arg.substring(KEYSTOREPASSWORD_SWITCH.length()); } else if( arg.startsWith(KEYPASSWORD_SWITCH)) { keyPassword = arg.substring(KEYPASSWORD_SWITCH.length()); } else if( arg.equals(VERIFY_SWITCH)) { isSign = false; } else { error("Unrecognized option: " + arg, -1); } } else if( null == inFileName ) { inFileName = arg; } else if( null == sigFileName ) { sigFileName = arg; } else { error("Too many file names: " + arg, -1); } } if( (null == keyId) || (null == inFileName) || (null == sigFileName) || (null == keyPassword) || (null == keyStorePassword )) { error("Missing argument!", -1); } return new Sign(isSign, keyId, keyStore, keyPassword, keyStorePassword, inFileName, sigFileName); } private static void error(String message, int exitCode) { if( null != message ) { System.err.println(message+"\n"); } System.err.println("Usage:"); System.err.println("\tSign [--verify] --keyid: [--keystore:] " + "--keystorepassword: --keypassword: "); System.exit(exitCode); } }