mirror of
https://github.com/howmp/reality
synced 2025-02-23 18:52:16 +08:00
143 lines
3.6 KiB
Go
143 lines
3.6 KiB
Go
package main
|
||
|
||
import (
|
||
"crypto/aes"
|
||
"crypto/cipher"
|
||
"crypto/ecdh"
|
||
"crypto/ecdsa"
|
||
"crypto/ed25519"
|
||
"crypto/elliptic"
|
||
"crypto/rand"
|
||
"crypto/tls"
|
||
"crypto/x509"
|
||
"encoding/base64"
|
||
"fmt"
|
||
)
|
||
|
||
func handshake() {
|
||
conn, err := tls.Dial("tcp", "www.qq.com:443", &tls.Config{})
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
err = conn.Handshake()
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
// conn.Close()
|
||
}
|
||
|
||
func main() {
|
||
signTest()
|
||
signTest2()
|
||
authkeyTest()
|
||
plaintext := make([]byte, 32)
|
||
if _, err := rand.Read(plaintext); err != nil {
|
||
panic(err)
|
||
}
|
||
copy(plaintext, []byte("REALITY"))
|
||
fmt.Println("plaintext", len(plaintext), plaintext)
|
||
}
|
||
|
||
func signTest() {
|
||
fmt.Println("signTest")
|
||
privateKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
data, err := x509.MarshalECPrivateKey(privateKey)
|
||
fmt.Println("priv", base64.RawURLEncoding.EncodeToString(data))
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
data, err = x509.MarshalPKIXPublicKey(&privateKey.PublicKey)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
fmt.Println("publ", base64.RawURLEncoding.EncodeToString(data))
|
||
hash := []byte("hello")
|
||
sign, err := ecdsa.SignASN1(rand.Reader, privateKey, hash[:])
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
fmt.Println("sign", len(sign), base64.RawURLEncoding.EncodeToString(sign))
|
||
ok := ecdsa.VerifyASN1(&privateKey.PublicKey, hash[:], sign)
|
||
fmt.Println("verify", ok)
|
||
|
||
}
|
||
func signTest2() {
|
||
pub, priv, err := ed25519.GenerateKey(nil)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
fmt.Println("priv", base64.RawURLEncoding.EncodeToString(priv))
|
||
fmt.Println("publ", base64.RawURLEncoding.EncodeToString(pub))
|
||
|
||
msg := []byte("1")
|
||
|
||
sign := ed25519.Sign(priv, msg)
|
||
fmt.Println("sign", len(sign), base64.RawURLEncoding.EncodeToString(sign))
|
||
ok := ed25519.Verify(pub, msg, sign)
|
||
fmt.Println("verify", ok)
|
||
|
||
}
|
||
|
||
func authkeyTest() {
|
||
fmt.Println("authkeyTest")
|
||
// 服务端持有私钥,客户端持有公钥
|
||
privateKeyServer, publicKeyClient := genEcdhX25519()
|
||
fmt.Println("priv", len(privateKeyServer), base64.RawURLEncoding.EncodeToString(privateKeyServer))
|
||
fmt.Println("publ", len(publicKeyClient), base64.RawURLEncoding.EncodeToString(publicKeyClient))
|
||
// tmp是每次Client Hello生成,其中公钥放在SessionID,私钥在客户端内存中
|
||
privateKeyTmp, publicKeyTmp := genEcdhX25519()
|
||
|
||
// 服务端进行密钥协商,得到authkey
|
||
authkey1, err := ecdhAuthKey(privateKeyServer, publicKeyTmp)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
|
||
// 客户端进行密钥协商,得到authkey
|
||
authkey2, err := ecdhAuthKey(privateKeyTmp, publicKeyClient)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
fmt.Println(base64.RawURLEncoding.EncodeToString(authkey1))
|
||
fmt.Println(base64.RawURLEncoding.EncodeToString(authkey2))
|
||
|
||
block, err := aes.NewCipher(authkey2)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
aead, err := cipher.NewGCM(block)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
fmt.Println("overhead", aead.Overhead(), "noncesize", aead.NonceSize())
|
||
ciphertext := aead.Seal(nil, make([]byte, aead.NonceSize()), []byte("1234567890123456"), nil)
|
||
fmt.Println(len(ciphertext), base64.RawURLEncoding.EncodeToString(ciphertext))
|
||
|
||
}
|
||
|
||
func ecdhAuthKey(privateKey []byte, publicKey []byte) ([]byte, error) {
|
||
|
||
priv, err := ecdh.X25519().NewPrivateKey(privateKey)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
|
||
pub, err := ecdh.X25519().NewPublicKey(publicKey)
|
||
if err != nil {
|
||
return nil, err
|
||
}
|
||
return priv.ECDH(pub)
|
||
}
|
||
|
||
func genEcdhX25519() ([]byte, []byte) {
|
||
priv, err := ecdh.X25519().GenerateKey(rand.Reader)
|
||
if err != nil {
|
||
panic(err)
|
||
}
|
||
return priv.Bytes(), priv.PublicKey().Bytes()
|
||
|
||
}
|