公鑰傳輸問題?
我們知道,通過用非對稱加密對對稱加密的密鑰進(jìn)行加密然后在網(wǎng)絡(luò)中傳輸感憾,解決了對稱加密密鑰的不安全傳輸問題,而非對稱加密的公鑰是不需要保密的令花,即可以在網(wǎng)絡(luò)中傳輸阻桅。那么問題來了,公鑰在傳輸?shù)倪^程中有沒有可能被攻擊呢兼都?答案是有的嫂沉,假設(shè)攻擊者在傳輸過程中劫持了發(fā)送方發(fā)送的公鑰,用自己的公鑰替代了真正的公鑰扮碧,那么接收方收到的就是假的公鑰趟章,這樣在密文傳輸過程中,接收方用的始終是假的公鑰慎王,同時劫持者也可以在網(wǎng)絡(luò)中解密數(shù)據(jù)蚓土,從而達(dá)到攻擊目的。
這樣便引發(fā)了一個問題赖淤,如何驗證公鑰北戏?
如何驗證公鑰?
發(fā)送方對公鑰進(jìn)行簽名
發(fā)送方將自己的公鑰簽名后發(fā)送出去漫蛔,接收方收到后用公鑰進(jìn)行簽名驗證嗜愈,很明顯,這樣做也是不可靠的莽龟,原因跟上面提到的一樣:公鑰無法認(rèn)證蠕嫁。
為此如果引入第三方認(rèn)證機(jī)構(gòu)(證書頒發(fā)機(jī)構(gòu)(CA))進(jìn)行中轉(zhuǎn)如何呢?發(fā)送方自己生成密鑰對毯盈,交由CA簽名并發(fā)送給接收方
然后將自己的身份信息和公鑰發(fā)送給CA剃毒,CA用自己的公私鑰來簽名收到公鑰信息,然后發(fā)送給接收方搂赋,同樣赘阀,這樣做也不能避免發(fā)送方發(fā)送出來的
數(shù)據(jù)是可靠的,因為中間人可以對公鑰進(jìn)行替換脑奠。-
申請者向CA發(fā)起密鑰生成請求基公,由CA生成密鑰并將密鑰對發(fā)送給申請人,而其他人則需要安裝證書才能與申請人進(jìn)行數(shù)據(jù)傳輸
CA生成公鑰-私鑰對后通過自己的公鑰對私鑰或者公鑰簽名后發(fā)送給申請人宋欺,接收者用CA的公鑰驗證簽名轰豆,然后收到數(shù)據(jù)。這樣在整個過程中無論是發(fā)送方還是接收方都只需要一次認(rèn)證即可齿诞,而CA的
公鑰一般是提前安裝在了PC上酸休,所以對于CA的公鑰,不存在傳輸隱患祷杈。注意:用于驗證簽名的CA公鑰斑司,我們稱之為根證書。由證書頒發(fā)機(jī)構(gòu)頒發(fā)但汞,并被預(yù)先安裝在電腦或者軟件中宿刮。
證書內(nèi)容
證書內(nèi)容如下圖:
1. 證書算法: 證書算法指明了使用的簽名算法,比如使用SHA-1的RSA或者使用SHA-2的ECDSA特占,還指明了參數(shù)(比如位長度)
2. 頒發(fā)者: 證書是誰頒發(fā)的
3. 有效期: 為一段時間糙置,指明證書有效期限
4. 主題: 包含證書申請人的身份信息,比如某個人或機(jī)構(gòu)的名字
5. 主題的公鑰: 指需要證書保護(hù)的公鑰是目,除了公鑰本身外谤饭,還包含算法和算法參數(shù)
6. 簽名: 此簽名覆蓋了證書所有其他的域
注意,每個簽名都包含兩個公鑰算法:一個是受保護(hù)的公鑰算法懊纳,另一個被證書用來簽名揉抵,且兩個算法并無關(guān)聯(lián)
證書申請
命令行生成
代碼生成(Golang)
package main
import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"io/ioutil"
"math/big"
mRand "math/rand"
"net"
"os"
"time"
)
func main() {
//獲取根證書
caBytes, err := ioutil.ReadFile("conf/root.cert")
if err != nil {
return
}
caBlock, _ := pem.Decode(caBytes)
rootCert, err := x509.ParseCertificate(caBlock.Bytes)
if err != nil {
return
}
privateKey, _ := rsa.GenerateKey(rand.Reader, 1024)
cert := x509.Certificate{
SerialNumber: big.NewInt(mRand.Int63()), //證書序列號
Subject: pkix.Name{ //這里填寫證書主題
Country: []string{"cn"},
Organization: []string{"cn", "company"},
OrganizationalUnit: []string{"test"},
Locality: []string{"Beijing"},
Province: []string{"Beijing"},
StreetAddress: []string{"ChangAn Street"},
},
NotAfter: time.Now().Add(7 * 24 * time.Hour), //有效期
NotBefore: time.Now(),
BasicConstraintsValid: true, //
IsCA: false,
EmailAddresses: []string{"test@gmail.com"},
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
}
//parent如果為自己則表示自簽證書,此處表示CA簽名的證書嗤疯,如果是CA簽發(fā)冤今,則公鑰需要是根證書的公鑰
//certBytes, err := x509.CreateCertificate(rand.Reader, &cert, &cert, &privateKey.PublicKey, privateKey)
certBytes, err := x509.CreateCertificate(rand.Reader, &cert, rootCert, &rootCert.PublicKey, privateKey)
if err != nil {
return
}
file, err := os.Create("conf/cert.pem")
if err != nil {
return
}
block := &pem.Block{
Type: "CERTIFICATE",
Bytes: certBytes,
}
if err = pem.Encode(file, block); err != nil {
return
}
file.Close()
block = &pem.Block{
Type: "RSA PRIVATE KEY",
Headers: nil,
Bytes: x509.MarshalPKCS1PrivateKey(privateKey),
}
file, err = os.Create("conf/private.pem")
if err = pem.Encode(file, block); err != nil {
return
}
file.Close()
}
引用資料
《深入淺出密碼學(xué)——常用加密技術(shù)原理與應(yīng)用》
最后
這里只是關(guān)于證書的簡要介紹,詳細(xì)了解還需要閱讀相關(guān)書籍茂缚。
原文連接
如有錯誤戏罢,還請指正屋谭!
Thanks!
附上代碼鏈接[github.com/pyihe/secret]