非对称加密,也称为Public Key Cryptography
,是一种加密系统,其中使用了两个不同但唯一相关的加密密钥。 使用一个密钥加密的数据可以用另一个密钥解密。 这些密钥称为“公钥和私钥对”,顾名思义,私钥在分发公钥时必须保持私钥。 最受欢迎的公钥算法是RSA,Diffie-Hellman,ElGamal,DSS。
1.生成公私钥对
根据您的平台,有几种方法可以生成公用-专用密钥对。 在此示例中,我们将使用Java创建一个配对。 在此示例中,我们将使用的密码算法是RSA。
GenerateKeys.java
package com.mkyong.keypair;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.PrivateKey;
import java.security.PublicKey;
public class GenerateKeys {
private KeyPairGenerator keyGen;
private KeyPair pair;
private PrivateKey privateKey;
private PublicKey publicKey;
public GenerateKeys(int keylength) throws NoSuchAlgorithmException, NoSuchProviderException {
this.keyGen = KeyPairGenerator.getInstance("RSA");
this.keyGen.initialize(keylength);
}
public void createKeys() {
this.pair = this.keyGen.generateKeyPair();
this.privateKey = pair.getPrivate();
this.publicKey = pair.getPublic();
}
public PrivateKey getPrivateKey() {
return this.privateKey;
}
public PublicKey getPublicKey() {
return this.publicKey;
}
public void writeToFile(String path, byte[] key) throws IOException {
File f = new File(path);
f.getParentFile().mkdirs();
FileOutputStream fos = new FileOutputStream(f);
fos.write(key);
fos.flush();
fos.close();
}
public static void main(String[] args) {
GenerateKeys gk;
try {
gk = new GenerateKeys(1024);
gk.createKeys();
gk.writeToFile("KeyPair/publicKey", gk.getPublicKey().getEncoded());
gk.writeToFile("KeyPair/privateKey", gk.getPrivateKey().getEncoded());
} catch (NoSuchAlgorithmException | NoSuchProviderException e) {
System.err.println(e.getMessage());
} catch (IOException e) {
System.err.println(e.getMessage());
}
}
}
输出:
2.创建一个文本文件进行加密
3.使用密钥对加密和解密数据
在此示例中,我们创建一个类,该类可以从它们的文件中加载公钥和私钥,然后使用它们来加密和解密String
和File
。 要运行此示例,您需要运行上面的代码以生成密钥或从下面下载源代码。
注意
您需要获取Apache Commons Codec并将其添加到程序中。
AsymmetricCryptography.java
package com.mkyong.asymmetric;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import org.apache.commons.codec.binary.Base64;
public class AsymmetricCryptography {
private Cipher cipher;
public AsymmetricCryptography() throws NoSuchAlgorithmException, NoSuchPaddingException {
this.cipher = Cipher.getInstance("RSA");
}
// https://docs.oracle.com/javase/8/docs/api/java/security/spec/PKCS8EncodedKeySpec.html
public PrivateKey getPrivate(String filename) throws Exception {
byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePrivate(spec);
}
// https://docs.oracle.com/javase/8/docs/api/java/security/spec/X509EncodedKeySpec.html
public PublicKey getPublic(String filename) throws Exception {
byte[] keyBytes = Files.readAllBytes(new File(filename).toPath());
X509EncodedKeySpec spec = new X509EncodedKeySpec(keyBytes);
KeyFactory kf = KeyFactory.getInstance("RSA");
return kf.generatePublic(spec);
}
public void encryptFile(byte[] input, File output, PrivateKey key)
throws IOException, GeneralSecurityException {
this.cipher.init(Cipher.ENCRYPT_MODE, key);
writeToFile(output, this.cipher.doFinal(input));
}
public void decryptFile(byte[] input, File output, PublicKey key)
throws IOException, GeneralSecurityException {
this.cipher.init(Cipher.DECRYPT_MODE, key);
writeToFile(output, this.cipher.doFinal(input));
}
private void writeToFile(File output, byte[] toWrite)
throws IllegalBlockSizeException, BadPaddingException, IOException {
FileOutputStream fos = new FileOutputStream(output);
fos.write(toWrite);
fos.flush();
fos.close();
}
public String encryptText(String msg, PrivateKey key)
throws NoSuchAlgorithmException, NoSuchPaddingException,
UnsupportedEncodingException, IllegalBlockSizeException,
BadPaddingException, InvalidKeyException {
this.cipher.init(Cipher.ENCRYPT_MODE, key);
return Base64.encodeBase64String(cipher.doFinal(msg.getBytes("UTF-8")));
}
public String decryptText(String msg, PublicKey key)
throws InvalidKeyException, UnsupportedEncodingException,
IllegalBlockSizeException, BadPaddingException {
this.cipher.init(Cipher.DECRYPT_MODE, key);
return new String(cipher.doFinal(Base64.decodeBase64(msg)), "UTF-8");
}
public byte[] getFileInBytes(File f) throws IOException {
FileInputStream fis = new FileInputStream(f);
byte[] fbytes = new byte[(int) f.length()];
fis.read(fbytes);
fis.close();
return fbytes;
}
public static void main(String[] args) throws Exception {
AsymmetricCryptography ac = new AsymmetricCryptography();
PrivateKey privateKey = ac.getPrivate("KeyPair/privateKey");
PublicKey publicKey = ac.getPublic("KeyPair/publicKey");
String msg = "Cryptography is fun!";
String encrypted_msg = ac.encryptText(msg, privateKey);
String decrypted_msg = ac.decryptText(encrypted_msg, publicKey);
System.out.println("Original Message: " + msg +
"\nEncrypted Message: " + encrypted_msg
+ "\nDecrypted Message: " + decrypted_msg);
if (new File("KeyPair/text.txt").exists()) {
ac.encryptFile(ac.getFileInBytes(new File("KeyPair/text.txt")),
new File("KeyPair/text_encrypted.txt"),privateKey);
ac.decryptFile(ac.getFileInBytes(new File("KeyPair/text_encrypted.txt")),
new File("KeyPair/text_decrypted.txt"), publicKey);
} else {
System.out.println("Create a file text.txt under folder KeyPair");
}
}
}
输出:
Original Message: Cryptography is fun!
Encrypted Message: NZY+9v4AWoADVBQiFmS8ake6dG8M9v4WDf4TSPKgGPoKeJtHxEWVFGFL57qR2mbuknn8WYjfjcN+BA/
RDsDQ9Q5SxQFLi8GE7A/6fdURjO+Vz3qYFaefpXccp7SnObKXnFfUNp00m5BtMSdTLEYfngF9UDBVYVFz0EZwuyP50xY=
Decrypted Message: Cryptography is fun!
加密文字:
解密文字:
下载源代码
参考文献
翻译自: https://mkyong.com/java/java-asymmetric-cryptography-example/