public class MyEncrypt {
public void saveToFile(String fileName, BigInteger mod, BigInteger exp) throws IOException {
ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
try {
oout.writeObject(mod);
oout.writeObject(exp);
} catch (Exception e) {
throw new IOException("Unexpected error", e);
} finally {
oout.close();
}
}
public static void main(String[] args) throws Exception {
MyEncrypt myEncrypt = new MyEncrypt();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(128);
KeyPair kp = kpg.genKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);
RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class);
myEncrypt.saveToFile("public.key", pub.getModulus(), pub.getPublicExponent());
myEncrypt.saveToFile("private.key", priv.getModulus(), priv.getPrivateExponent());
String encString = myEncrypt.bytes2String(myEncrypt.rsaEncrypt("pritesh".getBytes()));
System.out.println("encrypted : " + encString);
String decString = myEncrypt.bytes2String(myEncrypt.rsaDecrypt(encString.getBytes()));
System.out.println("decrypted : " + decString);
}
PublicKey readKeyFromFile(String keyFileName) throws Exception {
InputStream in = new FileInputStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in));
try {
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(keySpec);
return pubKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
PrivateKey readPrivateKeyFromFile(String keyFileName) throws Exception {
InputStream in = new FileInputStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in));
try {
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey pubKey = fact.generatePrivate(keySpec);
return pubKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
public byte[] rsaEncrypt(byte[] data) throws Exception {
byte[] src = new byte[] { (byte) 0xbe, (byte) 0xef };
PublicKey pubKey = this.readKeyFromFile("public.key");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] cipherData = cipher.doFinal(data);
return cipherData;
}
public byte[] rsaDecrypt(byte[] data) throws Exception {
byte[] src = new byte[] { (byte) 0xbe, (byte) 0xef };
PrivateKey pubKey = this.readPrivateKeyFromFile("private.key");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, pubKey);
byte[] cipherData = cipher.doFinal(data);
return cipherData;
}
private String bytes2String(byte[] bytes) {
StringBuilder string = new StringBuilder();
for (byte b: bytes) {
String hexString = Integer.toHexString(0x00FF & b);
string.append(hexString.length() == 1 ? "0" + hexString : hexString);
}
return string.toString();
}
}
我收到此错误:
Exception in thread "main" java.security.InvalidParameterException: RSA keys must be at least 512 bits long
at sun.security.rsa.RSAKeyPairGenerator.initialize(RSAKeyPairGenerator.java:70)
at java.security.KeyPairGenerator$Delegate.initialize(KeyPairGenerator.java:631)
at java.security.KeyPairGenerator.initialize(KeyPairGenerator.java:340)
at MyEncrypt.main(MyEncrypt.java:42)
我从http://www.javamex.com/tutorials/cryptography/rsa_encryption_2.shtml示例
创建了这个类
public class MyEncrypt {
static final String HEXES = "0123456789ABCDEF";
byte[] buf = new byte[1024];
public void saveToFile(String fileName, BigInteger mod, BigInteger exp) throws IOException {
ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
try {
oout.writeObject(mod);
oout.writeObject(exp);
} catch (Exception e) {
throw new IOException("Unexpected error", e);
} finally {
oout.close();
}
}
public static void main(String[] args) throws Exception {
MyEncrypt myEncrypt = new MyEncrypt();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.genKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);
RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class);
myEncrypt.saveToFile("public.key", pub.getModulus(), pub.getPublicExponent());
myEncrypt.saveToFile("private.key", priv.getModulus(), priv.getPrivateExponent());
String encString = myEncrypt.rsaEncrypt("pritesh");
System.out.println("encrypted : " + encString);
String decString = myEncrypt.rsaDecrypt(encString);
System.out.println("decrypted : " + decString);
String main_file_path = "resume.doc";
String main_encrypt_file_path = "encrypt.doc";
String main_decrypt_file_path = "decrypt.doc";
myEncrypt.rsaEncrypt(new FileInputStream(main_file_path),new FileOutputStream(main_encrypt_file_path));
// Decrypt
myEncrypt.rsaDecrypt(new FileInputStream(main_encrypt_file_path),new FileOutputStream(main_decrypt_file_path));
}
PublicKey readKeyFromFile(String keyFileName) throws Exception {
InputStream in = new FileInputStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in));
try {
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(keySpec);
return pubKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
PrivateKey readPrivateKeyFromFile(String keyFileName) throws Exception {
InputStream in = new FileInputStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in));
try {
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey pubKey = fact.generatePrivate(keySpec);
return pubKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
public String rsaEncrypt(String plaintext) throws Exception {
PublicKey pubKey = this.readKeyFromFile("public.key");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes("UTF-8"));
return this.byteToHex(ciphertext);
}
public void rsaEncrypt(InputStream in, OutputStream out) throws Exception {
try {
PublicKey pubKey = this.readKeyFromFile("public.key");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
// Bytes written to out will be encrypted
out = new CipherOutputStream(out, cipher);
// Read in the cleartext bytes and write to out to encrypt
int numRead = 0;
while ((numRead = in.read(buf)) >= 0){
out.write(buf, 0, numRead);
}
out.close();
}
catch (java.io.IOException e){
e.printStackTrace();
}
}
public void rsaDecrypt(InputStream in, OutputStream out) throws Exception {
try {
PrivateKey pubKey = this.readPrivateKeyFromFile("private.key");
Cipher dcipher = Cipher.getInstance("RSA");
dcipher.init(Cipher.DECRYPT_MODE, pubKey);
// Bytes read from in will be decrypted
in = new CipherInputStream(in, dcipher);
// Read in the decrypted bytes and write the cleartext to out
int numRead = 0;
while ((numRead = in.read(buf)) >= 0) {
out.write(buf, 0, numRead);
}
out.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
public String rsaDecrypt(String hexCipherText) throws Exception {
PrivateKey pubKey = this.readPrivateKeyFromFile("private.key");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, pubKey);
String plaintext = new String(cipher.doFinal(this.hexToByte(hexCipherText)), "UTF-8");
return plaintext;
}
public static String byteToHex( byte [] raw ) {
if ( raw == null ) {
return null;
}
final StringBuilder hex = new StringBuilder( 2 * raw.length );
for ( final byte b : raw ) {
hex.append(HEXES.charAt((b & 0xF0) >> 4))
.append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}
public static byte[] hexToByte( String hexString){
int len = hexString.length();
byte[] ba = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
ba[i/2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i+1), 16));
}
return ba;
}
static final String HEXES = "0123456789ABCDEF";
byte[] buf = new byte[1024];
public void saveToFile(String fileName, BigInteger mod, BigInteger exp) throws IOException {
ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
try {
oout.writeObject(mod);
oout.writeObject(exp);
} catch (Exception e) {
throw new IOException("Unexpected error", e);
} finally {
oout.close();
}
}
public static void main(String[] args) throws Exception {
MyEncrypt myEncrypt = new MyEncrypt();
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(2048);
KeyPair kp = kpg.genKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);
RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class);
myEncrypt.saveToFile("public.key", pub.getModulus(), pub.getPublicExponent());
myEncrypt.saveToFile("private.key", priv.getModulus(), priv.getPrivateExponent());
String encString = myEncrypt.rsaEncrypt("pritesh");
System.out.println("encrypted : " + encString);
String decString = myEncrypt.rsaDecrypt(encString);
System.out.println("decrypted : " + decString);
String main_file_path = "resume.doc";
String main_encrypt_file_path = "encrypt.doc";
String main_decrypt_file_path = "decrypt.doc";
myEncrypt.rsaEncrypt(new FileInputStream(main_file_path),new FileOutputStream(main_encrypt_file_path));
// Decrypt
myEncrypt.rsaDecrypt(new FileInputStream(main_encrypt_file_path),new FileOutputStream(main_decrypt_file_path));
}
PublicKey readKeyFromFile(String keyFileName) throws Exception {
InputStream in = new FileInputStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in));
try {
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(keySpec);
return pubKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
PrivateKey readPrivateKeyFromFile(String keyFileName) throws Exception {
InputStream in = new FileInputStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in));
try {
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey pubKey = fact.generatePrivate(keySpec);
return pubKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
public String rsaEncrypt(String plaintext) throws Exception {
PublicKey pubKey = this.readKeyFromFile("public.key");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
byte[] ciphertext = cipher.doFinal(plaintext.getBytes("UTF-8"));
return this.byteToHex(ciphertext);
}
public void rsaEncrypt(InputStream in, OutputStream out) throws Exception {
try {
PublicKey pubKey = this.readKeyFromFile("public.key");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.ENCRYPT_MODE, pubKey);
// Bytes written to out will be encrypted
out = new CipherOutputStream(out, cipher);
// Read in the cleartext bytes and write to out to encrypt
int numRead = 0;
while ((numRead = in.read(buf)) >= 0){
out.write(buf, 0, numRead);
}
out.close();
}
catch (java.io.IOException e){
e.printStackTrace();
}
}
public void rsaDecrypt(InputStream in, OutputStream out) throws Exception {
try {
PrivateKey pubKey = this.readPrivateKeyFromFile("private.key");
Cipher dcipher = Cipher.getInstance("RSA");
dcipher.init(Cipher.DECRYPT_MODE, pubKey);
// Bytes read from in will be decrypted
in = new CipherInputStream(in, dcipher);
// Read in the decrypted bytes and write the cleartext to out
int numRead = 0;
while ((numRead = in.read(buf)) >= 0) {
out.write(buf, 0, numRead);
}
out.close();
} catch (java.io.IOException e) {
e.printStackTrace();
}
}
public String rsaDecrypt(String hexCipherText) throws Exception {
PrivateKey pubKey = this.readPrivateKeyFromFile("private.key");
Cipher cipher = Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, pubKey);
String plaintext = new String(cipher.doFinal(this.hexToByte(hexCipherText)), "UTF-8");
return plaintext;
}
public static String byteToHex( byte [] raw ) {
if ( raw == null ) {
return null;
}
final StringBuilder hex = new StringBuilder( 2 * raw.length );
for ( final byte b : raw ) {
hex.append(HEXES.charAt((b & 0xF0) >> 4))
.append(HEXES.charAt((b & 0x0F)));
}
return hex.toString();
}
public static byte[] hexToByte( String hexString){
int len = hexString.length();
byte[] ba = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
ba[i/2] = (byte) ((Character.digit(hexString.charAt(i), 16) << 4) + Character.digit(hexString.charAt(i+1), 16));
}
return ba;
}
它适用于文本文件,但在docx和video这样的文件上有问题吗?
答案 0 :(得分:3)
错误说明了一切:您使用128的密钥集进行初始化,RSA期望至少为512。
答案 1 :(得分:0)
您有多个问题:
Java不支持大小小于512的RSA密钥.2048位是更好的选择。所以改变密钥长度:
kpg.initialize(2048);
String.getBytes()不是bytes2String()的逆操作。加密后,将字节转换为十六进制字符串。但是在解密之前将这个十六进制字符串转换为ASCII表示形式,这会产生一个太长的字节数组。相反,使用类似的东西来转换十六进制字符串:
private byte[] string2bytes(String s) {
int len = s.length();
byte[] res = new byte[len / 2];
for (int i = 0; i < len; i += 2) {
res[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4)
+ Character.digit(s.charAt(i+1), 16));
}
return res;
}
然后调用它而不是String.getBytes():
// Note, this line is not completely fixed yet
String decString =
myEncrypt.bytes2String(
myEncrypt.rsaDecrypt(
myEncrypt.string2bytes(encString)
)
);
最后你遇到了相反的问题。您的bytes2String()方法不会反转String.getBytes()操作。你加密了&#34; pritesh&#34; .getBytes()的输出,这就是你从解密操作中获得的。现在你必须将它转换回String。 String(byte []) - 构造函数将为您执行此操作:
String decString =
new String(
myEncrypt.rsaDecrypt(
myEncrypt.string2bytes(encString)
)
);
答案 2 :(得分:0)
最后的答案
public class MyEncrypt {
public static final int AES_Key_Size = 128;
Cipher pkCipher, aesCipher;
byte[] aesKey;
SecretKeySpec aeskeySpec;
public static void main(String[] args) throws Exception {
//MyEncrypt.createRSAKeys(); //call to generated RSA keys
MyEncrypt secure = new MyEncrypt();
// to encrypt a file
secure.makeKey();
secure.saveKey(new File("keys/ase.key"), "keys/public.key");
secure.encrypt(new File("test/sample.pdf"), new File("test/encrypt_sample.pdf"));
// to decrypt it again
secure.loadKey(new File("keys/ase.key"), "keys/private.key");
secure.decrypt(new File("test/encrypt_sample.pdf"), new File("test/decrypted_sample.pdf"));
}
/**
* Constructor: creates ciphers
*/
public MyEncrypt() throws GeneralSecurityException {
// create RSA public key cipher
pkCipher = Cipher.getInstance("RSA");
// create AES shared key cipher
aesCipher = Cipher.getInstance("AES");
}
public static void createRSAKeys() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(512);
KeyPair kp = kpg.genKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);
RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class);
saveToFile("keys/public.key", pub.getModulus(), pub.getPublicExponent());
saveToFile("keys/private.key", priv.getModulus(), priv.getPrivateExponent());
System.out.println("RSA public & private keys are generated");
}
private static void saveToFile(String fileName, BigInteger mod, BigInteger exp) throws IOException {
ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
try {
oout.writeObject(mod);
oout.writeObject(exp);
} catch (Exception e) {
throw new IOException("Unexpected error", e);
} finally {
oout.close();
}
}
/**
* Creates a new AES key
*/
public void makeKey() throws NoSuchAlgorithmException {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(AES_Key_Size);
SecretKey key = kgen.generateKey();
aesKey = key.getEncoded();
aeskeySpec = new SecretKeySpec(aesKey, "AES");
}
/**
* Encrypts the AES key to a file using an RSA public key
*/
public void saveKey(File out, String publicKeyFile) throws IOException, GeneralSecurityException {
try {
// read public key to be used to encrypt the AES key
byte[] encodedKey = new byte[(int)publicKeyFile.length()];
new FileInputStream(publicKeyFile).read(encodedKey);
// create public key
//X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);
//KeyFactory kf = KeyFactory.getInstance("RSA");
//PublicKey pk = kf.generatePublic(publicKeySpec);
PublicKey pk = this.readPublicKeyFromFile(publicKeyFile);
// write AES key
pkCipher.init(Cipher.ENCRYPT_MODE, pk);
CipherOutputStream os = new CipherOutputStream(new FileOutputStream(out), pkCipher);
os.write(aesKey);
os.close();
} catch (Exception e) {
//throw new Exception("Saving key exception", e);
}
}
private PublicKey readPublicKeyFromFile(String keyFileName) throws Exception {
InputStream in = new FileInputStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in));
try {
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(keySpec);
return pubKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
private PrivateKey readPrivateKeyFromFile(String keyFileName) throws Exception {
InputStream in = new FileInputStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in));
try {
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey pubKey = fact.generatePrivate(keySpec);
return pubKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
/**
* Decrypts an AES key from a file using an RSA private key
*/
public void loadKey(File in, String privateKeyFile) throws GeneralSecurityException, IOException {
try {
// read private key to be used to decrypt the AES key
byte[] encodedKey = new byte[(int)privateKeyFile.length()];
new FileInputStream(privateKeyFile).read(encodedKey);
// create private key
//PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey);
//KeyFactory kf = KeyFactory.getInstance("RSA");
//PrivateKey pk = kf.generatePrivate(privateKeySpec);
PrivateKey pk = this.readPrivateKeyFromFile(privateKeyFile);
// read AES key
pkCipher.init(Cipher.DECRYPT_MODE, pk);
aesKey = new byte[AES_Key_Size/8];
CipherInputStream is = new CipherInputStream(new FileInputStream(in), pkCipher);
is.read(aesKey);
aeskeySpec = new SecretKeySpec(aesKey, "AES");
} catch (Exception e) {
}
}
/**
* Encrypts and then copies the contents of a given file.
*/
public void encrypt(File in, File out) throws IOException, InvalidKeyException {
aesCipher.init(Cipher.ENCRYPT_MODE, aeskeySpec);
FileInputStream is = new FileInputStream(in);
CipherOutputStream os = new CipherOutputStream(new FileOutputStream(out), aesCipher);
copy(is, os);
os.close();
}
/**
* Decrypts and then copies the contents of a given file.
*/
public void decrypt(File in, File out) throws IOException, InvalidKeyException {
aesCipher.init(Cipher.DECRYPT_MODE, aeskeySpec);
CipherInputStream is = new CipherInputStream(new FileInputStream(in), aesCipher);
FileOutputStream os = new FileOutputStream(out);
copy(is, os);
is.close();
os.close();
}
/**
* Copies a stream.
*/
private void copy(InputStream is, OutputStream os) throws IOException {
int i;
byte[] b = new byte[1024];
while((i=is.read(b))!=-1) {
os.write(b, 0, i);
}
}
public static final int AES_Key_Size = 128;
Cipher pkCipher, aesCipher;
byte[] aesKey;
SecretKeySpec aeskeySpec;
public static void main(String[] args) throws Exception {
//MyEncrypt.createRSAKeys(); //call to generated RSA keys
MyEncrypt secure = new MyEncrypt();
// to encrypt a file
secure.makeKey();
secure.saveKey(new File("keys/ase.key"), "keys/public.key");
secure.encrypt(new File("test/sample.pdf"), new File("test/encrypt_sample.pdf"));
// to decrypt it again
secure.loadKey(new File("keys/ase.key"), "keys/private.key");
secure.decrypt(new File("test/encrypt_sample.pdf"), new File("test/decrypted_sample.pdf"));
}
/**
* Constructor: creates ciphers
*/
public MyEncrypt() throws GeneralSecurityException {
// create RSA public key cipher
pkCipher = Cipher.getInstance("RSA");
// create AES shared key cipher
aesCipher = Cipher.getInstance("AES");
}
public static void createRSAKeys() throws Exception {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(512);
KeyPair kp = kpg.genKeyPair();
RSAPublicKey publicKey = (RSAPublicKey) kp.getPublic();
RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();
KeyFactory fact = KeyFactory.getInstance("RSA");
RSAPublicKeySpec pub = fact.getKeySpec(kp.getPublic(), RSAPublicKeySpec.class);
RSAPrivateKeySpec priv = fact.getKeySpec(kp.getPrivate(), RSAPrivateKeySpec.class);
saveToFile("keys/public.key", pub.getModulus(), pub.getPublicExponent());
saveToFile("keys/private.key", priv.getModulus(), priv.getPrivateExponent());
System.out.println("RSA public & private keys are generated");
}
private static void saveToFile(String fileName, BigInteger mod, BigInteger exp) throws IOException {
ObjectOutputStream oout = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(fileName)));
try {
oout.writeObject(mod);
oout.writeObject(exp);
} catch (Exception e) {
throw new IOException("Unexpected error", e);
} finally {
oout.close();
}
}
/**
* Creates a new AES key
*/
public void makeKey() throws NoSuchAlgorithmException {
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(AES_Key_Size);
SecretKey key = kgen.generateKey();
aesKey = key.getEncoded();
aeskeySpec = new SecretKeySpec(aesKey, "AES");
}
/**
* Encrypts the AES key to a file using an RSA public key
*/
public void saveKey(File out, String publicKeyFile) throws IOException, GeneralSecurityException {
try {
// read public key to be used to encrypt the AES key
byte[] encodedKey = new byte[(int)publicKeyFile.length()];
new FileInputStream(publicKeyFile).read(encodedKey);
// create public key
//X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encodedKey);
//KeyFactory kf = KeyFactory.getInstance("RSA");
//PublicKey pk = kf.generatePublic(publicKeySpec);
PublicKey pk = this.readPublicKeyFromFile(publicKeyFile);
// write AES key
pkCipher.init(Cipher.ENCRYPT_MODE, pk);
CipherOutputStream os = new CipherOutputStream(new FileOutputStream(out), pkCipher);
os.write(aesKey);
os.close();
} catch (Exception e) {
//throw new Exception("Saving key exception", e);
}
}
private PublicKey readPublicKeyFromFile(String keyFileName) throws Exception {
InputStream in = new FileInputStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in));
try {
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPublicKeySpec keySpec = new RSAPublicKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PublicKey pubKey = fact.generatePublic(keySpec);
return pubKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
private PrivateKey readPrivateKeyFromFile(String keyFileName) throws Exception {
InputStream in = new FileInputStream(keyFileName);
ObjectInputStream oin = new ObjectInputStream(new BufferedInputStream(in));
try {
BigInteger m = (BigInteger) oin.readObject();
BigInteger e = (BigInteger) oin.readObject();
RSAPrivateKeySpec keySpec = new RSAPrivateKeySpec(m, e);
KeyFactory fact = KeyFactory.getInstance("RSA");
PrivateKey pubKey = fact.generatePrivate(keySpec);
return pubKey;
} catch (Exception e) {
throw new RuntimeException("Spurious serialisation error", e);
} finally {
oin.close();
}
}
/**
* Decrypts an AES key from a file using an RSA private key
*/
public void loadKey(File in, String privateKeyFile) throws GeneralSecurityException, IOException {
try {
// read private key to be used to decrypt the AES key
byte[] encodedKey = new byte[(int)privateKeyFile.length()];
new FileInputStream(privateKeyFile).read(encodedKey);
// create private key
//PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encodedKey);
//KeyFactory kf = KeyFactory.getInstance("RSA");
//PrivateKey pk = kf.generatePrivate(privateKeySpec);
PrivateKey pk = this.readPrivateKeyFromFile(privateKeyFile);
// read AES key
pkCipher.init(Cipher.DECRYPT_MODE, pk);
aesKey = new byte[AES_Key_Size/8];
CipherInputStream is = new CipherInputStream(new FileInputStream(in), pkCipher);
is.read(aesKey);
aeskeySpec = new SecretKeySpec(aesKey, "AES");
} catch (Exception e) {
}
}
/**
* Encrypts and then copies the contents of a given file.
*/
public void encrypt(File in, File out) throws IOException, InvalidKeyException {
aesCipher.init(Cipher.ENCRYPT_MODE, aeskeySpec);
FileInputStream is = new FileInputStream(in);
CipherOutputStream os = new CipherOutputStream(new FileOutputStream(out), aesCipher);
copy(is, os);
os.close();
}
/**
* Decrypts and then copies the contents of a given file.
*/
public void decrypt(File in, File out) throws IOException, InvalidKeyException {
aesCipher.init(Cipher.DECRYPT_MODE, aeskeySpec);
CipherInputStream is = new CipherInputStream(new FileInputStream(in), aesCipher);
FileOutputStream os = new FileOutputStream(out);
copy(is, os);
is.close();
os.close();
}
/**
* Copies a stream.
*/
private void copy(InputStream is, OutputStream os) throws IOException {
int i;
byte[] b = new byte[1024];
while((i=is.read(b))!=-1) {
os.write(b, 0, i);
}
}