但遇到了一個問題,
駑鈍的我花了快一個星期才從別人的程式碼中搞出自己想要的部份,
程式的目的是要讓我在程式碼中調用存放的密碼字串時,
不要讓密碼以明碼方式存放在程式或是設定檔中,
那參考了別人寫的程式碼後,終於弄出自己要的程式碼,
程式碼部份分了兩部份,第一部份(此篇)是用來製作加密密碼的文字檔,並產出公私鑰檔案,
另一部份則是用來讀取加密密碼的文字檔及私鑰來解出密碼字串(下篇文章貼上)。
以下附上程式碼供參考。
package PassWordEncrypt;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Paths;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
public class PassWordEncrypt {
public static void main(String[] args) throws Exception {
// 資料來源參考:https://jimwayne.blogspot.com/2012/06/java.html
// 檔案存放路徑 (公私鑰及加密後密碼檔)
String path = "src\\";
SecureRandom random = new SecureRandom();
random.setSeed("test".getBytes());
// 產生金鑰組 Generate the key pair (public key and private key).
KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
// 指定金鑰長度2048-bit Specify that the key should be 2048-bit.
keygen.initialize(2048,random); //若拿掉random就不會每執行一次就變一次金鑰
KeyPair generatedKeyPair = keygen.generateKeyPair();
// 印出金鑰,以base64編碼 Print the key. The key will be encoded by Base64.
printKeyPair(generatedKeyPair);
// 儲存金鑰 Store the key as files.
saveKeyPair(path, generatedKeyPair);
// 讀取金鑰 Load the keys
KeyPair loadedKeyPair = loadKeyPair(path, "RSA"); // Load the keys from files
// 印出金鑰以確認金鑰相同 Print the loaded key pair to ensure that they are exactly the same.
printKeyPair(loadedKeyPair);
// 字串使用加密金鑰並存檔,再使用解密金鑰讀取存檔
String password = "123!@#"; //注意! 設定密碼字串,請依需求修改此處
byte [] passwordB = password.getBytes();
System.out.println("密碼加密前 = " + new String (passwordB) + "\n" );
byte [] passwordEncrypt = encrypt (passwordB,generatedKeyPair.getPublic() );
System.out.println("密碼加密後 = " + new String (passwordEncrypt) );
File passwordFile = new File (path + "password.txt");
try (FileOutputStream foss = new FileOutputStream(passwordFile)) {
foss.write(passwordEncrypt);
foss.close();
}
FileInputStream fileInputStream = new FileInputStream( path + "password.txt" );
DataInputStream dis = new DataInputStream(fileInputStream);
// count the available bytes form the input stream
int count = dis.available();
// create buffer
byte[] bs = new byte[count];
// read data into buffer
dis.read(bs);
dis.close();
byte [] passwordDecrypt= decrypt (bs, loadedKeyPair.getPrivate() );
String ReadPasswordFile = new String (passwordDecrypt);
System.out.println("\n" + "密碼從檔案讀取後" + "\n" + "解密取得之字串= " + ReadPasswordFile );
}
//公鑰加密
public static byte[] encrypt(byte[] content, PublicKey publicKey) throws Exception{
Cipher cipher=Cipher.getInstance("RSA");//java預設"RSA"="RSA/ECB/PKCS1Padding"
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(content);
}
//私鑰解密
public static byte[] decrypt(byte[] content, PrivateKey privateKey) throws Exception{
Cipher cipher=Cipher.getInstance("RSA");
cipher.init(Cipher.DECRYPT_MODE, privateKey);
return cipher.doFinal(content);
}
public static void printKeyPair(KeyPair keyPair) {
Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
System.out.println ("public key: " + Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded()));
Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
System.out.println ("private key: " + Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded()) );
}
public static void saveKeyPair(String path, KeyPair keyPair) throws IOException {
PrivateKey privateKey = keyPair.getPrivate();
PublicKey publicKey = keyPair.getPublic();
// Store Public Key.
File fileForPublicKey = Paths.get(path, "public.key").toFile();
//log.trace("Public key will be output to '{}'.", fileForPublicKey);
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(publicKey.getEncoded());
try (FileOutputStream fos = new FileOutputStream(fileForPublicKey)) {
fos.write(x509EncodedKeySpec.getEncoded());
}
// Store Private Key.
File fileForPrivateKey = Paths.get(path, "private.key").toFile();
PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(privateKey.getEncoded());
try (FileOutputStream fos = new FileOutputStream(fileForPrivateKey)) {
fos.write(pkcs8EncodedKeySpec.getEncoded());
}
}
// Load the keys from files.
public static KeyPair loadKeyPair(String path, String algorithm)
throws IOException, NoSuchAlgorithmException, InvalidKeySpecException {
// Initiate the factory with specified algorithm.
KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
// Read public key from file.
File fileForPublicKey = Paths.get(path, "public.key").toFile();
PublicKey publicKey = null;
try (FileInputStream fis = new FileInputStream(fileForPublicKey)) {
byte[] loadedBytes = new byte[(int) fileForPublicKey.length()];
fis.read(loadedBytes);
X509EncodedKeySpec spec = new X509EncodedKeySpec(loadedBytes);
publicKey = keyFactory.generatePublic(spec);
}
// Read private key from file.
File fileForPrivateKey = Paths.get(path, "private.key").toFile();
//log.trace("Private key will be loaded from '{}'.", fileForPrivateKey);
PrivateKey privateKey = null;
try (FileInputStream fis = new FileInputStream(fileForPrivateKey)) {
byte[] loadedBytes = new byte[(int) fileForPrivateKey.length()];
fis.read(loadedBytes);
PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(loadedBytes);
privateKey = keyFactory.generatePrivate(privateKeySpec);
}
return new KeyPair(publicKey, privateKey);
}
}
沒有留言:
張貼留言