我夕
在實際的應用中單單只有對稱式加密是不夠的,更多的時候是對稱式加密與非對稱式加密結合使用,非對稱式加密(公開金鑰加密)特點速度慢、加密和解密的鑰匙不相同,加密的方式是:
* 公開金鑰加密-私密金鑰解密
* 私密金鑰加密-公開金鑰解密
這兩種,這裡給大家示範下第一種方式,剩下一種大家自己測試下。
步驟:
得到keyPairGenerator的執行個體對象,並調用其generateKeyPair()方法建立KeyPair對象。
調用KeyPair對象的getPrivate和getPublic方法,分別得到PrivateKey對象和PublicKey對象。
得到Cipher的執行個體對象,並調用其init()方法指定PrivateKey對象或PublicKey對象,並指定要進行加密、還是進行解密操作。
調用Cipher對象的doFinal()方法完成加密或解密操作。
代碼如下:
package com.study.security;import java.io.ByteArrayOutputStream;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.ObjectInputStream;import java.io.ObjectOutputStream;import java.security.Key;import java.security.KeyPair;import java.security.KeyPairGenerator;import java.security.PrivateKey;import java.security.PublicKey;import javax.crypto.Cipher;import javax.crypto.CipherInputStream;/** * 非對稱式加密-公開金鑰加密 * 公開金鑰加密-私密金鑰解密 * 私密金鑰加密-公開金鑰解密 * @author 我夕 * */public class PublicSecret {/** * @param args */public static void main(String[] args) throws Exception{publicEncrypt();privatecEncrypt();}/** * 公開金鑰加密 * @throws Exception */private static void publicEncrypt() throws Exception{Cipher cipher=Cipher.getInstance("RSA");//產生鑰匙對KeyPairGenerator keyPairGenerator=KeyPairGenerator.getInstance("RSA");KeyPair keyPair=keyPairGenerator.generateKeyPair();PublicKey publicKey= keyPair.getPublic();PrivateKey privateKey=keyPair.getPrivate();cipher.init(Cipher.ENCRYPT_MODE, publicKey);//前面做加密時都是用預設的編碼,如果加密的資料是中文會出現亂碼,現在改成中文的資料進行測試以下byte[] results=cipher.doFinal("我是要被加密的資料!".getBytes("UTF-8"));//儲存密鑰,由於是公開金鑰加密,解密時得用私密金鑰,所以這裡要對產生的私密金鑰進行存檔saveKey(privateKey, "key_public.key");saveData(results, "key_pubData.data");System.out.println("加密後的資料:"+new String(results));}/** * 私密金鑰解密 * @throws Exception */private static void privatecEncrypt() throws Exception{//讀取key與dataKey privateKey=readKey("key_public.key");byte[] results=readData("key_pubData.data");Cipher cipher=Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, privateKey);//不要忘記了加編碼格式,不然亂碼System.out.println("解密後的資料:"+new String(cipher.doFinal(results),"UTF-8"));//===================讀資料的另一種寫法,如以下========================FileInputStream fis=new FileInputStream("key_pubData.data");CipherInputStream cis=new CipherInputStream(fis,cipher);ByteArrayOutputStream arrayOutputStream=new ByteArrayOutputStream();int len=0;byte[] data=new byte[1024];while((len=cis.read(data))!=-1){arrayOutputStream.write(data, 0, len);}byte[] result2=arrayOutputStream.toByteArray();arrayOutputStream.close();cis.close();System.out.println("解密後的資料(讀取資料的另一種方式):"+new String(result2,"UTF-8"));}/** * 儲存資料的方法 * @param results * @param dataName * @throws Exception */public static void saveData(byte[] results,String dataName)throws Exception{FileOutputStream fosData=new FileOutputStream(dataName);fosData.write(results);fosData.close();}/** * 讀取資料的方法 * @param dataName * @return byte[] * @throws Exception */public static byte[] readData(String dataName)throws Exception{FileInputStream fisDat= new FileInputStream(dataName);//讀位元據ByteArrayOutputStream arrayOutputStream=new ByteArrayOutputStream();int len=0;byte[] data=new byte[1024];while((len=fisDat.read(data))!=-1){arrayOutputStream.write(data, 0, len);}byte[] result=arrayOutputStream.toByteArray();arrayOutputStream.close();fisDat.close();return result;}/** * 儲存密鑰的方法 * @param key * @param keyName * @throws Exception */public static void saveKey(Key key,String keyName) throws Exception{FileOutputStream foskey=new FileOutputStream(keyName);ObjectOutputStream oos=new ObjectOutputStream(foskey);oos.writeObject(key);oos.close();foskey.close();}/** * 讀取密鑰的方法 * @param keyName * @return Key * @throws Exception */public static Key readKey(String keyName) throws Exception{FileInputStream fiskey=new FileInputStream(keyName);ObjectInputStream oiskey=new ObjectInputStream(fiskey);Key key=(Key)oiskey.readObject();oiskey.close();fiskey.close();return key;}}
運行結果: