但遇到了一個問題,
駑鈍的我花了快一個星期才從別人的程式碼中搞出自己想要的部份,
程式的目的是要讓我在程式碼中調用存放的密碼字串時,
不要讓密碼以明碼方式存放在程式或是設定檔中,
那參考了別人寫的程式碼後,終於弄出自己要的程式碼,
程式碼部份分了兩部份,第一部份(此篇)是用來製作加密密碼的文字檔,並產出公私鑰檔案,
另一部份則是用來讀取加密密碼的文字檔及私鑰來解出密碼字串(下篇文章貼上)。
以下附上程式碼供參考。
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); } }
沒有留言:
張貼留言