| import org.rivoreo.crypto.ECIES; |
| import org.rivoreo.crypto.ECIES_XTEA; |
| import java.io.FileInputStream; |
| import java.io.FileOutputStream; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.io.IOException; |
| |
| class ECIES_Tool { |
| private static void keygen() throws IOException { |
| //char buf[2 * ECIES_KEY_SIZE + 1]; |
| //ECIES.PrivateKey priv; |
| //ECIES.PublicKey pub; |
| //ECIES ecies = new ECIES_XTEA(ECIES.SECTDomainParameters.sect409r1); |
| ECIES ecies = new ECIES_XTEA(ECIES.SECTDomainParameters.sect571r1); |
| ECIES.PrivateKey priv = ecies.create_privatekey(); |
| ECIES.PublicKey pub = ecies.create_publickey(); |
| ecies.generate_keys(priv, pub); /* generate a public/private key pair */ |
| /* |
| hex_dump(buf, pub.x, ECIES_KEY_SIZE); printf("%s:", buf); |
| hex_dump(buf, pub.y, ECIES_KEY_SIZE); printf("%s\n", buf); |
| hex_dump(buf, priv.k, ECIES_KEY_SIZE); printf("%s\n", buf); |
| */ |
| /* |
| print_bytes(pub.x); |
| System.out.print(':'); |
| print_bytes_line(pub.y); |
| print_bytes_line(priv.k); |
| */ |
| /* |
| System.out.printf("%s:%s\n%s\n", |
| hex_dump(pub.x, pub.x.length), |
| hex_dump(pub.y, pub.y.length), |
| hex_dump(priv.k, priv.k.length)); |
| */ |
| FileOutputStream fos = new FileOutputStream("publickey"); |
| fos.write(pub.x); |
| fos.write(pub.y); |
| fos.close(); |
| fos = new FileOutputStream("privatekey"); |
| fos.write(priv.k); |
| fos.close(); |
| System.out.println("publickey and privatekey are saved into current directory"); |
| } |
| |
| private static final int CHUNK_SIZE = 8 * 1024; |
| |
| private static int read_chunk(InputStream stm, byte[] raw, int offset, int len) throws IOException { |
| len = stm.read(raw, offset, len); |
| return len; |
| } |
| |
| private static void write_all(OutputStream stm, final byte[] raw, int offset, int len) throws IOException { |
| stm.write(raw, offset, len); |
| } |
| |
| private static void encrypt(String pubkey) throws IOException { |
| //ECIES ecies = new ECIES_XTEA(ECIES.SECTDomainParameters.sect409r1); |
| ECIES ecies = new ECIES_XTEA(ECIES.SECTDomainParameters.sect571r1); |
| ECIES.PublicKey pub = ecies.new PublicKey(); |
| //ECIES.PublicKey pub = ecies.create_publickey(); |
| /* |
| int len = load_bytes(pub.x, pubkey); |
| if(len < 0) { |
| System.err.println("Invalid public key x"); |
| return; |
| } |
| len = load_bytes(pub.y, pubkey.substring(len)); |
| if(len < 0) { |
| System.err.println("Invalid public key y"); |
| return; |
| } |
| */ |
| FileInputStream fis = new FileInputStream(pubkey); |
| fis.read(pub.x); |
| fis.read(pub.y); |
| fis.close(); |
| |
| ECIES.Stream stm = ecies.new Stream(); |
| byte[] enc = new byte[ecies.ECIES_START_OVERHEAD]; |
| ecies.encrypt_start(stm, enc, pub); |
| write_all(System.out, enc, 0, ecies.ECIES_START_OVERHEAD); |
| |
| enc = new byte[CHUNK_SIZE + ecies.ECIES_CHUNK_OVERHEAD]; |
| while(true) { |
| int len = read_chunk(System.in, enc, 0, CHUNK_SIZE); |
| if(len <= 0) return; |
| ecies.encrypt_chunk(stm, enc, len); |
| write_all(System.out, enc, 0, len + ecies.ECIES_CHUNK_OVERHEAD); |
| } |
| } |
| |
| private static void decrypt(String privkey) throws IOException { |
| //ECIES ecies = new ECIES_XTEA(ECIES.SECTDomainParameters.sect409r1); |
| ECIES ecies = new ECIES_XTEA(ECIES.SECTDomainParameters.sect571r1); |
| ECIES.PrivateKey priv = ecies.new PrivateKey(); |
| //ECIES.PrivateKey priv = new ECIES.PrivateKey(ecies.getClass()); |
| /* |
| if(load_bytes(priv.k, privkey) < 0) { |
| System.err.println("Invalid private key"); |
| return; |
| } |
| */ |
| FileInputStream fis = new FileInputStream(privkey); |
| fis.read(priv.k); |
| fis.close(); |
| |
| ECIES.Stream stm = ecies.new Stream(); |
| byte[] enc = new byte[ecies.ECIES_START_OVERHEAD]; |
| int len = read_chunk(System.in, enc, 0, ecies.ECIES_START_OVERHEAD); |
| if(len < ecies.ECIES_START_OVERHEAD) { |
| System.err.printf("%d < %d\n", len, ecies.ECIES_START_OVERHEAD); |
| return; |
| } |
| len = ecies.decrypt_start(stm, enc, priv); |
| if(len < 0) { |
| System.err.println("ecies.decrypt_start failed"); |
| return; |
| } |
| |
| enc = new byte[CHUNK_SIZE + ecies.ECIES_CHUNK_OVERHEAD]; |
| while(true) { |
| len = read_chunk(System.in, enc, 0, CHUNK_SIZE + ecies.ECIES_CHUNK_OVERHEAD); |
| if(len <= 0) return; |
| if(ecies.decrypt_chunk(stm, enc, len - ecies.ECIES_CHUNK_OVERHEAD) < 0) { |
| System.err.println("decrypt_chunk failed"); |
| return; |
| } |
| write_all(System.out, enc, 0, len - ecies.ECIES_CHUNK_OVERHEAD); |
| } |
| } |
| |
| private static void print_usage() { |
| System.err.println("Usage: ecies-tool <command> [parameters]\n" + |
| " [k]eygen -- generate public/private key pair\n" + |
| " [e]ncrypt [public-key-x:public-key-y] -- encrypt stdin to stdout using public key\n" + |
| " [d]ecrypt [private-key] -- decript stdin to stdout using private key\n"); |
| } |
| |
| public static void main(String[] a) throws IOException { |
| if(a.length < 1 || (a[0].charAt(0) != 'k' && a.length < 2)) { |
| print_usage(); |
| return; |
| } |
| switch(a[0].charAt(0)) { |
| case 'k': |
| //keygen(a.length > 1 ? a[1] : null); |
| keygen(); |
| return; |
| case 'e': |
| encrypt(a[1]); |
| return; |
| case 'd': |
| decrypt(a[1]); |
| return; |
| } |
| print_usage(); |
| } |
| } |