Ⅰ https是如何工作的
在java 1.2時,引入JCR(java 加密擴展)系統,用來負責java中的密鑰和證書。
我們都知道,如果我們想要加密或解密一些信息,我們必須要有一個密鑰。這好比你想要開門或者鎖門,必須要有鑰匙一樣。
在java中,密鑰由KeyGenerator或KeyPairGenerator生成。前者用來生成對稱密鑰,後者用來生成非對稱密鑰。
對稱密鑰:使用同一個密鑰進行加密和解密
非對稱密鑰:使用不同的密鑰進行加密和解密,通常被稱為公鑰(public key)和私鑰(private key)。 公鑰可以廣泛傳播,但是私鑰只有其所有者知道。在一個安全的非對稱密鑰加密方案中,當信息用公鑰加密後,只有用私鑰才能解密。所以,即使一個黑客拿到你公鑰加密過後的信息,也無法解密它,因為它沒有配對的私鑰。這樣,傳輸的消息就是安全的。
在現實中,如果你進入到鑽石專賣店中想要買一顆鑽石,你怎麼知道鑽石是真的?作為一個普通人來說,我們沒有鑽石方面的知識,但是如果這鑽石有個由美國政府頒發的許可證,我們就會相信它是真的。(去過珠寶店的同學都知道,每件珠寶都有自己的鑒定書)
證書的作用也是如此。在計算機世界中,它可能是包含一些密鑰,是另一個證書(姑且稱之為證書B好了)。這些密鑰是我們需要的,而證書B是一個許可證,用來證明這個證書是可信賴的。
做個簡短的解釋,每個鑽石都有自己的「身份證書」,但是如何說明這個身份證書是合法的,而不是自己偽造的?因此,我們需要一個權威的機構來證明這個鑽石的身份證書是合法的,如果這個鑽石的身份是合法的,該權威機構就會為其頒發一個「許可證」,這個許可證就相當於上面我們說到的證書B。可以看到,證書B的目的就是證明這個身份證書是這個鑽石的身份證書,即證明某某東西是某某東西的東西
問題來了:我們怎麼確定證書B是可信賴的呢?這個問題非常棒。
Android已經把將近150個CA根證書(數字證書認證機構認證過的證書)內置在我們手機中。這150多個證書被全世界信賴,他們就像是美國的大法官。
這150多個證書類似我們剛才說的證書B,分別用來證明某某東西是某某東西的東西
B證書中里有另外一個證書(姑且稱之為C證書),我們通過檢查C來確定C是否是可信任的。。。通過這個證書鏈,如果我們找到的最後一個或根證書 和手機中預置的150個證書中某個相同,我們就可以這個證書原件(此處就是B)
這里我對證書鏈進行說明。證書之間的信任關系是可以嵌套的。比如,CA信任D,D信任C,C信任B
,B信任A。。。這就是證書鏈。只要我們信任證書鏈上的頭一個證書,那麼後續的證書都是可以信任的。這里也就是如果我信任了證書CA,那麼後面的D,C,B,A都是可以信任的。這里來打個比方,架設軍隊中的每個士兵都只認識自己的直接上級,那麼這時候總司令怎麼確認某個士兵是自己部隊 當中的呢?總司令(CA)會問的直接下級(D),而司令的直接下級又會找自己的直接下級,依次往下找…如果最後能找到這個士兵直屬上級,那就說明這個士兵是該部隊當中的。
附:證書有多種格式
x.509
x.509證書通常用於包含一個公鑰
PKCS12
PKCS12證書通常用來包含一個私鑰。因此,PKCS12需要密碼才能打開。
現在我們來了解https部分。Https(http over ssl)包含上面提到的加密和證書兩部分,被設計用來在Internet安全進行通信。
如何安全通信呢?對稱加密是我們最先想到的方案:將數據進行加密,然後將加密過的數據和密鑰同時傳到伺服器,伺服器使用這個密鑰解密加密過後的數據。
上面這張圖片已經清楚的展示了HTTPS工作的流程。
1.[Server]生成一對密鑰:公鑰和私鑰,我們稱之為「KeyPub」,「KeyPri」
2.[Server]服務端將公鑰(KeyPub)發送到客戶端
3.[Client]生成一個對稱密鑰(姑且稱之為key2),然後用key2加密數據。
4.[Client]使用公鑰(KeyPub)加密key2.這時,key2是安全的,因為只有服務度有私鑰KeyPri
5.[Client]發送用key2加密後的信息及用KeyPub加密過的key2到服務端
6.[Server]服務端使用KeyPri解密得到加密過的key2,得到真正的key2
7.[Server]使用key2解密消息正文。這樣,數據就被安全的傳輸到了服務端。
由於對稱加密比非對稱加密快,https決定使用對稱加密來加密數據,使用非對稱加密對稱加密生成的密鑰,以確保安全
Ⅱ Java生成RSA非對稱型加密的公鑰和私鑰
非對稱型加密非常適合多個客戶端和伺服器之間的秘密通訊 客戶端使用同一個公鑰將明文加密 而這個公鑰不能逆向的解密 密文發送到伺服器後有伺服器端用私鑰解密 這樣就做到了明文的加密傳送
非對稱型加密也有它先天的缺點 加密 解密速度慢制約了它的發揮 如果你有大量的文字需要加密傳送 建議你通過非對稱型加密來把對稱型 密鑰 分發到客戶端 及時更新對稱型 密鑰
import java io *;
import java security *;
import javax crypto *;
import javax crypto spec *;
/**
* <p>Title: RSA非對稱型加密的公鑰和私鑰</p>
* <p>Description: </p>
* <p>Copyright: Copyright (c) </p>
* <p>Company: </p>
* @author not attributable
* @version
*/
public class KeyRSA {
private KeyPairGenerator kpg = null;
private KeyPair kp = null;
private PublicKey public_key = null;
private PrivateKey private_key = null;
private FileOutputStream public_file_out = null;
private ObjectOutputStream public_object_out = null;
private FileOutputStream private_file_out = null;
private ObjectOutputStream private_object_out = null;
/**
* 構造函數
* @param in 指定密匙長度(取值范圍 ~ )
* @throws NoSuchAlgorithmException 異常
*/
public KeyRSA(int in String address) throws NoSuchAlgorithmException FileNotFoundException IOException
{
kpg = KeyPairGenerator getInstance( RSA ); //創建 密匙對 生成器
kpg initialize(in); //指定密匙長度(取值范圍 ~ )
kp = kpg genKeyPair(); //生成 密匙對 其中包含著一個公匙和一個私匙的信息
public_key = kp getPublic(); //獲得公匙
private_key = kp getPrivate(); //獲得私匙
//保存公匙
public_file_out = new FileOutputStream(address + /public_key dat );
public_object_out = new ObjectOutputStream(public_file_out);
public_object_out writeObject(public_key);
//保存私匙
private_file_out = new FileOutputStream(address + /private_key dat );
private_object_out = new ObjectOutputStream(private_file_out);
private_object_out writeObject(private_key);
}
public static void main(String[] args) {
try {
System out println( 私匙和公匙保存到C盤下的文件中 );
new KeyRSA( c:/ );
}
catch (IOException ex) {
}
catch (NoSuchAlgorithmException ex) {
}
}
lishixin/Article/program/Java/hx/201311/26592
Ⅲ java 中的Cipher類RSA方式能不能用私鑰加密公鑰解密,完整解釋下
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
keyGen.initialize(1024);
KeyPair key = keyGen.generateKeyPair();
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
//把第二個參數改為 key.getPrivate()
cipher.init(Cipher.ENCRYPT_MODE, key.getPublic());
byte[] cipherText = cipher.doFinal("Message".getBytes("UTF8"));
System.out.println(new String(cipherText, "UTF8"));
//把第二個參數改為key.getPublic()
cipher.init(Cipher.DECRYPT_MODE, key.getPrivate());
byte[] newPlainText = cipher.doFinal(cipherText);
System.out.println(new String(newPlainText, "UTF8"));
正常的用公鑰加密私鑰解密就是這個過程,如果按私鑰加密公鑰解密,只要按備注改2個參數就可以。
但是我要提醒樓主,你要公鑰解密,公鑰是公開的,相當於任何人都查到公鑰可以解密。
你是想做簽名是吧。
Ⅳ JAVA寫RSA加密,公鑰私鑰都是一樣的,為什麼每次加密的結果不一樣
有可能是當前的環境字元編碼不一樣,例如加密一邊用的是GBK,解密那邊用的是UTF-8編碼,所以結果就會不同步。
Ⅳ JAVA寫RSA加密,公鑰私鑰都是一樣的,為什麼每次加密的結果不一樣
因為rsa是非對稱加密,它使用的是隨機大素數的抽取,每次隨機生成的,所以每次加密的結果不可能一樣