HTTPS那些事 用java實現HTTPS工作原理
今天被問到關於https原理的問題,結果由於知識掌握不牢靠,停留於表面,很多細節都無法回答清楚,於是決定把https的原理弄個明白,廢話不多說,我們先看看https的定義
(由於很久未寫部落格,排版有些凌亂,請諒解)
一:什麼是https協議
在說HTTPS之前先說說什麼是HTTP,HTTP就是我們平時瀏覽網頁時候使用的一種協議。HTTP協議傳輸的資料都是未加密的,也就是明文的,因此使 用HTTP協議傳輸隱私資訊非常不安全。為了保證這些隱私資料能加密傳輸,於是網景公司設計了SSL(Secure Sockets Layer)協議用於對HTTP協議傳輸的資料進行加密,從而就誕生了HTTPS。SSL目前的版本是3.0,被IETF(Internet Engineering Task Force)定義在RFC 6101中,之後IETF對SSL 3.0進行了升級,於是出現了TLS(Transport
Layer Security) 1.0,定義在RFC 2246。實際上我們現在的HTTPS都是用的TLS協議,但是由於SSL出現的時間比較早,並且依舊被現在瀏覽器所支援,因此SSL依然是HTTPS的 代名詞,但無論是TLS還是SSL都是上個世紀的事情,SSL最後一個版本是3.0,今後TLS將會繼承SSL優良血統繼續為我們進行加密服務。目前 TLS的版本是1.2,定義在RFC 5246中,暫時還沒有被廣泛的使用。對歷史感興趣的朋友可以參考
二:https的工作原理是什麼
HTTPS在傳輸資料之前需要客戶端(瀏覽器)與服務端(網站)之間進行一次握手,在握 手過程中將確立雙方加密傳輸資料的密碼資訊,通常情況下會配合數字證書實現。
TLS/SSL協議不僅僅是一套加密傳輸的協議,更是一件經過藝術家精心設計的藝術品,TLS/SSL中使用 非對稱加密,對稱加密以及HASH演算法。
這裡我們先看看這上面提到的幾種技術(如果你對這些技術已經非常瞭解,那麼請跳過該段落,直接到段落三)
- 數字證書
數字證書是一種權威性的電子文件,由權威公正的第三方機構,即CA中心簽發的證書。它以數字證書為核心的加密技術可以對網路上傳輸的資訊進行加密和解密、數字簽名和簽名驗證,確保網上傳遞資訊的機密性、完整性。 使用了數字證書,即使您傳送的資訊在網上被他人截獲,甚至您丟失了個人的賬戶、密碼等資訊,仍可以保證您的賬戶、資金安全。
它能提供在Internet上進行身份驗證的一種權威性電子文件,人們可以在網際網路交往中用它來證明自己的身份和識別對方的身份。當然在數字證書認證的過程中證書認證中心(CA)作為權威的、公正的、可信賴的第三方,其作用是至關重要的.如何判斷數字認證中心公正第三方的地位是權威可信的。VeriSign、GeoTrust、Thawte 是國際權威數字證書頒發認證機構的“三巨頭”,其中,應用最廣的為VerSign簽發的電子商務數字證書。
CER(Canonical Encoding Rules,規範編碼格式) 是數字證書的一種編碼格式,它是BER(Basic Encoding Rules 基本編碼格式) 的一個變種,比BER 規定得更嚴格。字尾的證書檔案有兩種編碼:
DER(Distinguished Encoding Rule 卓越編碼格式) 同樣是BER的一個變種,DER使用定長模式。
PKCS(Public-Key Cryptography Standards,公鑰加密標準) 由RSA實驗室和其他安全系統開發商為公鑰密碼的發展而制定的一系列標準。
pfx是指以pkcs#12格式儲存的證書和相應私鑰。
在Security程式設計中,有幾種典型的密碼交換資訊檔案格式:
DER-encoded certificate: .cer, .crt
PEM-encoded message: .pem
PKCS#12 Personal Information Exchange: .pfx, .p12
PKCS#10 Certification Request: .p10 .csr
PKCS#7 cert request response: .p7r
PKCS#7 binary message: .p7b .p7c .spc
cer/.crt 是用於存放證書,它是2進位制形式存放
pem 跟crt/cer的區別是它以Ascii來表示
pfx/p12 用於存放個人證書/私鑰,他通常包含保護密碼,2進位制方式
p10 .csr 是證書請求
p7r是CA對證書請求的回覆,只用於匯入
p7b .p7c .spc 以樹狀展示證書鏈(certificate chain),同時也支援單個證書,不含私鑰
- 非對稱加密演算法
1976年,美國學者Dime和Henman為解決資訊公開傳送和金鑰管理問題,提出一種新的金鑰交換協議,允許在不安全的媒體上的通訊雙方交換資訊,安全地達成一致的金鑰,這就是"公開金鑰系統"。相對於"對稱加密演算法"這種方法也叫做"非對稱加密演算法"。與對稱加密演算法不同,非對稱加密演算法需要兩個金鑰:公開金鑰(publickey)和私有密(privatekey)。公開金鑰與私有金鑰是一對,如果用公開金鑰對資料進行加密,只有用對應的私有金鑰才能解密;如果用私有金鑰對資料進行加密,那麼只有用對應的公開金鑰才能解密。因為加密和解密使用的是兩個不同的金鑰,所以這種演算法叫作非對稱加密演算法。
非對稱加密演算法實現機密資訊交換的基本過程是:甲方生成一對金鑰並將其中的一把作為公用金鑰向其它方公開;得到該公用金鑰的乙方使用該金鑰對機密資訊進行加密後再發送給甲方;甲方再用自己儲存的另一把專用金鑰對加密後的資訊進行解密。甲方只能用其專用金鑰解密由其公用金鑰加密後的任何資訊。非對稱加密演算法的保密性比較好,它消除了終端使用者交換金鑰的需要,但加密和解密花費時間長、速度慢,它不適合於對檔案加密而只適用於對少量資料進行加密。 經典的非對稱加密演算法如RSA演算法等安全性都相當高. 非對稱加密的典型應用是數字簽名。採用雙鑰密碼系統的加密方法,在一個過程中使用兩個金鑰,一個用於加密,另一個用於解密,這種加密方法稱為非對稱加密,也稱為公鑰加密,因為其中一個金鑰是公開的(另一個則需要保密)。
DH (Diffie-Hellman)
Diffie-Hellman演算法(D-H演算法),金鑰一致協議。是由公開金鑰密碼體制的奠基人Diffie和Hellman所提出的一種思想。簡單的說就是允許兩名使用者在公開媒體上交換資訊以生成"一致"的、可以共享的金鑰。換句話說,就是由甲方產出一對金鑰(公鑰、私鑰),乙方依照甲方公鑰產生乙方金鑰對(公鑰、私鑰)。以此為基線,作為資料傳輸保密基礎,同時雙方使用同一種對稱加密演算法構建本地金鑰(SecretKey)對資料加密。這樣,在互通了本地金鑰(SecretKey)演算法後,甲乙雙方公開自己的公鑰,使用對方的公鑰和剛才產生的私鑰加密資料,同時可以使用對方的公鑰和自己的私鑰對資料解密。不單單是甲乙雙方兩方,可以擴充套件為多方共享資料通訊,這樣就完成了網路互動資料的安全通訊!該演算法源於中國的同餘定理——中國餘數定理。RSA
RSA公鑰加密演算法是1977年由Ron Rivest、Adi Shamirh和LenAdleman在(美國麻省理工學院)開發的。RSA取名來自開發他們三者的名字。RSA是目前最有影響力的公鑰加密演算法,它能夠抵抗到目前為止已知的所有密碼攻擊,已被ISO推薦為公鑰資料加密標準。RSA演算法基於一個十分簡單的數論事實:將兩個大素數相乘十分容易,但那時想要對其乘積進行因式分解卻極其困難,因此可以將乘積公開作為加密金鑰。EL Gamal
EL Gamal演算法是公鑰密碼體制中的一種 ,在密碼學中佔有重要的地位。但該演算法所採用的冪剩餘計算耗時太多的問題 ,一直是制約其廣泛應用的瓶頸問題。提出一種通過建表 ,以及對傳統二進位制演算法進行改進 ,即將指數進行 2 k進位制化 ,減少原 BR演算法迭代次數 ,提高加密解密速度的演算法。ECC
ECC (Elliptical Curve Cryptography,橢圓曲線加密)演算法不橢圓曲線理論為基礎,在建立金鑰時可以更快,更小,並且更有效,它是用大質數的積來產生。目前Java 6公提供了DH和RSA兩種演算法實現,通過Bouncy Castle可以實現Elmal演算法支援,另ECC加密演算法,目前沒有開源元件提支援
- 對稱加密演算法
對加密和解密使用相同金鑰的加密演算法。由於其速度,對稱性加密通常在訊息傳送方需要加密大量資料時使用。對稱性加密也稱為金鑰加密。對稱式資料加密的方式的工作原理如圖。所謂對稱,就是採用這種加密方法的雙方使用方式用同樣的金鑰進行加密和解密。金鑰實際上是一種演算法,通訊傳送方使用這種演算法加密資料,接收方再以同樣的演算法解密資料。因此對稱式加密本身不是安全的。常用的對稱加密有:
DES、IDEA、RC2、RC4、SKIPJACK演算法等 。
採用單鑰密碼系統的加密方法,同一個金鑰可以同時用作資訊的加密和解密,這種加密方法稱為對稱加密,也稱為單金鑰加密。
- HASH演算法
常用的摘要演算法包括MD5,SHA1,SHA256
訊息摘要演算法的特點:
① 無論輸入的訊息有多長,計算出來的訊息摘要的長度總是固定的。
② 訊息摘要看起來是“隨機的”。這些位元看上去是胡亂的雜湊在一起的。
③ 一般地,只要輸入的訊息不同,對其進行摘要以後產生的摘要訊息也必不相同;但相同的輸入必會產生相同的輸出。
④ 訊息摘要函式是無陷門的單向函式,即只能進行正向的資訊摘要,而無法從摘要中恢復出任何的訊息,甚至根本就找不到任何與原資訊相關的資訊。
⑤ 好的摘要演算法,無法找到兩條訊息,是它們的摘要相同。訊息摘要(Message Digest)又稱為數字摘要(Digital Digest)。它是一個唯一對應一個訊息或文字的固定長度的值,它由一個單向Hash加密函式對訊息進行作用而產生。如果訊息在途中改變了,則接收者通過對收到訊息的新產生的摘要與原摘要比較,就可知道訊息是否被改變了。因此訊息摘要保證了訊息的完整性。訊息摘要採用單向Hash 函式將需加密 的明文"摘要"成一串128bit的密文,這一串密文亦稱為數字指紋(Finger Print),它有固定的長度,且不同的明文摘要成密文,其結果總是不同的,而同樣的明文其摘要必定一致 。這樣這串摘要便可成為驗證明文是否是"真身"的"指紋"了。
HASH函式的抗衝突性使得如果一段明文稍有變化,哪怕只更改該段落的一個字母,通過雜湊演算法作用後都將產生不同的值。而HASH演算法的單向性使得要找到到雜湊值相同的兩個不 同的輸入訊息,在計算上是不可能的。所以資料的雜湊值,即訊息摘要,可以檢驗資料的完整性。雜湊函式的這種對不同的輸入能夠生成不同的值的特性使得無法找到兩個具有相同雜湊值的輸入。因此,如果兩個文件經雜湊轉換後成為相同的值,就可以肯定它們是同一文件。 所以,當希望有效地比較兩個資料塊時,就可以比較它們的雜湊值。例如,可以通過比較郵件傳送前和傳送後的雜湊值來驗證該郵件在傳遞時是否修改
訊息摘要演算法的主要特徵是加密過程不需要金鑰,並且經過加密的資料無法被解密,只有輸入相同的明文資料經過相同的訊息摘要演算法才能得到相同的密文。訊息摘要演算法不存在 金鑰的管理與分發問題,適合於分散式網路相同上使用。由於其加密計算的工作量相當可觀,所以以前的這種演算法通常只用於資料量有限的情況下的加密,例如計算機的口令就是 用不可逆加密演算法加密的。
三 https握手的過程詳細描述
1.瀏覽器將自己支援的一套加密規則傳送給網站,如RSA加密演算法,DES對稱加密演算法,SHA1摘要演算法
2.網站從中選出一組加密演算法與HASH演算法,並將自己的身份資訊以證書的形式發回給瀏覽器。證書裡面包含了網站地址,加密公鑰,以及證書的頒發機構等資訊(證書中的私鑰只能用於伺服器端進行解密,在握手的整個過程中,都用到了證書中的公鑰和瀏覽器傳送給伺服器的隨機密碼以及對稱加密演算法)
3.獲得網站證書之後瀏覽器要做以下工作:
a) 驗證證書的合法性(頒發證書的機構是否合法,證書中包含的網站地址是否與正在訪問的地址一致等),如果證書受信任,則瀏覽器欄裡面會顯示一個小鎖頭,否則會給出證書不受信的提示。
b) 如果證書受信任,或者是使用者接受了不受信的證書,瀏覽器會生成一串隨機數的密碼,並用證書中提供的公鑰加密。
c) 使用約定好的HASH演算法計算握手訊息(如SHA1),並使用生成的隨機數對訊息進行加密,最後將之前生成的被公鑰加密的隨機數密碼,HASH摘要值一起傳送給伺服器
4.網站接收瀏覽器發來的資料之後要做以下的操作:
a) 使用自己的私鑰將資訊解密並取出瀏覽器傳送給伺服器的隨機密碼,使用密碼解密瀏覽器發來的握手訊息,並驗證HASH是否與瀏覽器發來的一致。
b) 使用隨機密碼加密一段握手訊息,傳送給瀏覽器。
5.瀏覽器解密並計算握手訊息的HASH,如果與服務端發來的HASH一致,此時握手過程結束,之後所有的通訊資料將由之前瀏覽器生成的隨機密碼並利用對稱加密演算法進行加密。
從上面的4個大的步驟可以看到,握手的整個過程使用到了數字證書、對稱加密、HASH摘要演算法,接下來我們用實際程式碼來實現整個過程
四 使用java程式碼模擬整個握手過程
一:準備工作
1、建立java證書,
C:\> keytool -genkey -alias wangyi -keypass wangyi -keyalg RSA -keysize 1024 -keystore https.keystore -storepass wangyi
2、將建立的證書儲存到C盤(為了方便演示)
C:\>keytool -export -keystore https.keystore -alias wangyi -file https.crt -storepass wangyi
二:程式碼實現
程式碼包含6個類,分別為:
名稱 | 說明 |
CertifcateUtils | 證書操作類 |
DesCoder | Des對稱加密和解密工具類 |
HttpsMockBase | https父類 |
HttpsMockClient | client類 |
HttpsMockServer | 伺服器類 |
SocketUtils | socket工具類 |
- package httpsmock;
- import java.io.ByteArrayInputStream;
- import java.io.FileInputStream;
- import java.io.InputStream;
- import java.security.KeyStore;
- import java.security.PrivateKey;
- import java.security.PublicKey;
- import java.security.cert.CertificateFactory;
- /**
- * Created by kingj on 2014/8/13.
- */
- public class CertifcateUtils {
- public static byte[] readCertifacates() throws Exception{
- CertificateFactory factory=CertificateFactory.getInstance("X.509");
- InputStream in=new FileInputStream("c:/https.crt");
- java.security.cert.Certificate cate=factory.generateCertificate(in);
- return cate.getEncoded();
- }
- public static byte[] readPrivateKey() throws Exception{
- KeyStore store=KeyStore.getInstance("JKS");
- InputStream in=new FileInputStream("c:/https.keystore");
- store.load(in,"wangyi".toCharArray());
- PrivateKey pk=(PrivateKey)store.getKey("wangyi","wangyi".toCharArray());
- return pk.getEncoded();
- }
- public static PrivateKey readPrivateKeys() throws Exception{
- KeyStore store=KeyStore.getInstance("JKS");
- InputStream in=new FileInputStream("c:/https.keystore");
- store.load(in,"wangyi".toCharArray());
- PrivateKey pk=(PrivateKey)store.getKey("wangyi","wangyi".toCharArray());
- return pk;
- }
- public static PublicKey readPublicKeys() throws Exception{
- CertificateFactory factory=CertificateFactory.getInstance("X.509");
- InputStream in=new FileInputStream("c:/https.crt");
- java.security.cert.Certificate cate=factory.generateCertificate(in);
- return cate.getPublicKey();
- }
- public static java.security.cert.Certificate createCertiface(byte b[]) throws Exception{
- CertificateFactory factory=CertificateFactory.getInstance("X.509");
- InputStream in=new ByteArrayInputStream(b);
- java.security.cert.Certificate cate=factory.generateCertificate(in);
- return cate;
- }
- public static String byte2hex(byte[] b) {
- String hs = "";
- String stmp = "";
- for (int n = 0; n < b.length; n++) {
- stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
- if (stmp.length() == 1) {
- hs = hs + "0" + stmp;
- } else {
- hs = hs + stmp;
- }
- }
- return hs.toUpperCase();
- }
- }
- package httpsmock;
- /**
- * Created by kingj on 2014/8/13.
- */
- import org.apache.commons.codec.binary.Hex;
- import java.security.Key;
- import java.security.SecureRandom;
- import javax.crypto.Cipher;
- import javax.crypto.KeyGenerator;
- import javax.crypto.SecretKey;
- import javax.crypto.SecretKeyFactory;
- import javax.crypto.spec.DESKeySpec;
- /**
- * DES Coder<br/>
- * secret key length: 56 bit, default: 56 bit<br/>
- * mode: ECB/CBC/PCBC/CTR/CTS/CFB/CFB8 to CFB128/OFB/OBF8 to OFB128<br/>
- * padding: Nopadding/PKCS5Padding/ISO10126Padding/
- * @author Aub
- *
- */
- public class DesCoder {
- /**
- * 金鑰演算法
- */
- private static final String KEY_ALGORITHM = "DES";
- private static final String DEFAULT_CIPHER_ALGORITHM = "DES/ECB/PKCS5Padding";
- // private static final String DEFAULT_CIPHER_ALGORITHM = "DES/ECB/ISO10126Padding";
- /**
- * 初始化金鑰
- *
- * @return byte[] 金鑰
- * @throws Exception
- */
- public static byte[] initSecretKey(SecureRandom random) throws Exception{
- //返回生成指定演算法的祕密金鑰的 KeyGenerator 物件
- KeyGenerator kg = KeyGenerator.getInstance(KEY_ALGORITHM);
- //初始化此金鑰生成器,使其具有確定的金鑰大小
- kg.init(random);
- //生成一個金鑰
- SecretKey secretKey = kg.generateKey();
- return secretKey.getEncoded();
- }
- /**
- * 轉換金鑰
-
相關推薦
HTTPS那些事 用java實現HTTPS工作原理
今天被問到關於https原理的問題,結果由於知識掌握不牢靠,停留於表面,很多細節都無法回答清楚,於是決定把https的原理弄個明白,廢話不多說,我們先看看https的定義 (由於很久未寫部落格,排版有些凌亂,請諒解) 一:什麼是https協議 在說HTTPS之前先說說什麼是
發新帖 HTTPS那些事(一)HTTPS原理
楔子 謠言粉碎機前些日子釋出的《用公共WiFi上網會危害銀行賬戶安全嗎?》,文中介紹了在使用HTTPS進行網路加密傳輸的一些情況,從回覆來看,爭議還是有的。隨著網路越來越普及,應用越來越廣泛,一些網路安全問題也會越來越引起網民的關注,在這裡和大家一起聊聊TLS/SSL也就是我們常說的HTTPS,從原理到實際
[轉] java實現https請求
width pub ogr row ctx str tput pic ide package com.lichmama.test.util; import java.io.ByteArrayOutputStream; import java.io.IOExcep
java實現https免證書認證
java實現https免證書認證 解決方法: 1.下載兩個包,httpclient-4.2.jar和httpcore-4.2.jar,複製以下程式碼就可使用。 2.呼叫類程式碼: String httpOrgCreateTest = "https://url
JAVA實現HTTPS協議POST請求JSON報文
package https; import java.io.ByteArrayOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.io.InputStream; impo
java實現https協議
import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.KeyMana
java 實現https
摘 要 JSSE是一個SSL和TLS的純Java實現,通過JSSE可以很容易地程式設計實現對HTTPS站點的訪問。但是,如果該站點的證書未經權威機構的驗證,JSSE將拒絕信任該證書從而不能訪問HTTPS站點。本文在簡要介紹JSSE的基礎上提出了兩種解決該問題的方法。引
HTTPS那些事(一) HTTPS原理
楔子 謠言粉碎機前些日子釋出的《用公共WiFi上網會危害銀行賬戶安全嗎?》,文中介紹了在使用HTTPS進行網路加密傳輸的一些情況,從回覆來看,爭議還是有的。隨著網路越來越普及,應用越來越廣泛,一些網路安全問題也會越來越引起網民的關注,在這裡和大家一起聊聊TLS
init.rc文件中面啟動c++程序,通過jni調用java實現
mini val sni ril urn runtime sport mco env </pre><p>註:假設是自己的myself.jar包,還要修改例如以下:</p><p>target/product/core_bas
再談用java實現Smtp發送郵件之Socket編程
~~ 成功 剛才 還要 登陸 computer and ont sys 很多其它內容歡迎訪問個人站點 http://icodeyou.com 前幾天利用Socket實現了用java語言搭建webserver,全程下來應該會對Socket這
用java實現一個簡單的單用戶登陸功能的思路
get 單用戶 這樣的 簡單的 lock ref 數據庫 清除 一個 引用 所謂“單用戶單賬戶登錄”是指:在同一系統中,一個用戶名不能在兩個地方同時登錄。 我們參照 QQ 實現效果:當某賬號在 A 處登錄後,在未退出的情況下,如果再到 B 處登錄,那麽,系統會擠下 A 處
用java實現的strstr函數的一些問題
符號 clas bsp 問題: pub spa 操作 記錄 位置 用java實現過程如下: 1 public static int strstr(char[] cArray1,char[] cArray2){ 2 if(cArray1!=null &&
用Java實現的選擇排序和冒泡排序
auth main sta -i str public java index 選擇 選擇排序 package cn.hxd.sort; /** * 選擇排序 * @author Administrator * */ public class SelectionSo
用Java實現字母排列的三角形
int true bst 字母 main println logs abcd rgs public class HomeWork03 { public static void main(String[] args) { String st
用java實現一個簡易編譯器1-詞法解析入門
new 概念 自加 我們 sta 數字 獲得 () 操作系統 本文對應代碼下載地址為: http://download.csdn.net/detail/tyler_download/9435103 視頻地址: http://v.youku.com/v_show/id_XMT
用java實現從命令行接收多個數字,求和之後輸出結果
system 程序流程圖 sta num 思想 pri for循環 含義 自動 1.設計思想 首先要了解從命令行輸入數字的含義,不需要在程序中自己定義。需要定義int類的num和sum。之後利用num=Integer.parseInt(arg);將String型轉化為int
數據結構(三) 用java實現七種排序算法。
得到 最簡 上傳 根節點 位置 中間 log 說明 堆排序 很多時候,聽別人在討論快速排序,選擇排序,冒泡排序等,都覺得很牛逼,心想,臥槽,排序也分那麽多種,就覺得別人很牛逼呀,其實不然,當我們自己去了解學習後發現,並沒有想象中那麽難,今天就一起總結一下各種排序
用Java實現AES加密(轉)
密鑰 工具 mex 嚴格 keys 生產 ner for 創建 一)什麽是AES? 高級加密標準(英語:Advanced Encryption Standard,縮寫:AES),是一種區塊加密標準。這個標準用來替代原先的DES,已經被多方分析且廣為全世界所使用。 那麽為什麽
java算法面試題:排序都有哪幾種方法?請列舉。用JAVA實現一個快速排序。選擇冒泡快速集合至少4種方法排序
算法 err div println rda print 算法面試 ++ 快速排序 package com.swift; import java.util.ArrayList; import java.util.Collections; import java.util
用java實現類似於中原六仔源碼搭建
void class a 分別是 super util ava 數據 import count() 由於是用Java實現的所以圖形顯示界面是通過java的GUI實現中原六仔源碼搭建的。企 娥:217 1793 408 首先先來介紹一下我們的最終成果。寫了四個類文件分