first commit
This commit is contained in:
@@ -0,0 +1,24 @@
|
||||
# mac 下的交叉编译
|
||||
```
|
||||
./config --prefix=/opt/openssl shared no-asm
|
||||
make
|
||||
cp -rf ./libcrypto.a ../bin/libcrypto_darwin.a
|
||||
make clean
|
||||
./Configure --prefix=/opt/openssl --cross-compile-prefix=x86_64-w64-mingw32- shared no-asm mingw64
|
||||
make
|
||||
cp -rf ./libcrypto.dll.a ../bin/libcrypto_windows.dll.a
|
||||
make clean
|
||||
./Configure --prefix=/opt/openssl --cross-compile-prefix=x86_64-linux-musl- shared no-asm linux-x86_64
|
||||
make
|
||||
cp -rf ./libcrypto.a ../bin/libcrypto_linux.a
|
||||
make clean
|
||||
```
|
||||
|
||||
windows:
|
||||
brew install mingw-w64
|
||||
CGO_ENABLED=1 GOOS=windows GOARCH=amd64 CC=x86_64-w64-mingw32-gcc go build main.go
|
||||
|
||||
linux:
|
||||
brew install FiloSottile/musl-cross/musl-cross
|
||||
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 CC=x86_64-linux-musl-gcc CGO_LDFLAGS="-static" go build -a main.go
|
||||
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build main.go
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,60 @@
|
||||
package cecdh
|
||||
|
||||
//import "C"
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
)
|
||||
|
||||
/*//GenerateEccKey GenerateEccKey2
|
||||
func GenerateEccKey() ([]byte, []byte) {
|
||||
pubKeyBuf := make([]byte, 57)
|
||||
priKeyBuf := make([]byte, 106)
|
||||
cPubKeyBuf := getCharPointer(pubKeyBuf)
|
||||
cPriKeyBuf := getCharPointer(priKeyBuf)
|
||||
//https://tools.ietf.org/html/rfc5480 Sect409k1.nid = 731
|
||||
C.GenerateECKey(713, cPubKeyBuf, cPriKeyBuf)
|
||||
return pubKeyBuf, priKeyBuf
|
||||
}
|
||||
|
||||
//ComputerECCKeyMD5 ComputerECCKeyMD52
|
||||
func ComputerECCKeyMD5(ecPubKey []byte, ecPriKey []byte) []byte {
|
||||
cEcPubKey := getCharPointer(ecPubKey)
|
||||
cEcPriKey := getCharPointer(ecPriKey)
|
||||
outAesKey := make([]byte, 16)
|
||||
cOutAesKey := getCharPointer(outAesKey)
|
||||
cPubKeyLen := C.int(len(ecPubKey))
|
||||
cPriKeyLen := C.int(len(ecPriKey))
|
||||
C.ComputerECCKeyMD5(cEcPubKey, cPubKeyLen, cEcPriKey, cPriKeyLen, cOutAesKey)
|
||||
|
||||
return outAesKey
|
||||
}
|
||||
*/
|
||||
|
||||
// GenerateEccKey GenerateEccKey2
|
||||
func GenerateEccKey() ([]byte, []byte) {
|
||||
newEllipticECDH := NewEllipticECDH(elliptic.P224())
|
||||
priKeyBuf, pubKeyBuf, err := newEllipticECDH.GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
return []byte{}, []byte{}
|
||||
}
|
||||
|
||||
return pubKeyBuf, priKeyBuf
|
||||
}
|
||||
|
||||
// ComputerECCKeyMD5 ComputerECCKeyMD52
|
||||
func ComputerECCKeyMD5(ecPubKey []byte, ecPriKey []byte) []byte {
|
||||
e := NewEllipticECDH(elliptic.P224())
|
||||
srvPubKey, ok := e.Unmarshal(ecPubKey)
|
||||
if !ok {
|
||||
return []byte{}
|
||||
}
|
||||
pwd, err := e.GenerateSharedSecret(ecPriKey, srvPubKey)
|
||||
if err != nil {
|
||||
return []byte{}
|
||||
}
|
||||
ctx := md5.New()
|
||||
_, _ = ctx.Write(pwd)
|
||||
return ctx.Sum(nil)
|
||||
}
|
||||
@@ -0,0 +1,129 @@
|
||||
package cecdh
|
||||
|
||||
/*
|
||||
#cgo windows CFLAGS: -I./openssl/include -DCGO_OS_WINDOWS=1
|
||||
#cgo darwin CFLAGS: -I./openssl/include -DCGO_OS_DARWIN=1
|
||||
#cgo linux CFLAGS: -I./openssl/include -DCGO_OS_LINUX=1
|
||||
#cgo windows LDFLAGS: -L./bin -lcrypto_windows -lstdc++
|
||||
#cgo darwin LDFLAGS: -L./bin -lcrypto_darwin -lstdc++
|
||||
#cgo linux LDFLAGS: -L./bin -lcrypto_linux -lstdc++
|
||||
|
||||
#include <stdio.h>
|
||||
#include "internal/cryptlib.h"
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/ec.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/cms.h>
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/md5.h>
|
||||
|
||||
int GenerateECKey(int nid, char* pubKey, char* priKey)
|
||||
{
|
||||
char buf[68] = {0};
|
||||
|
||||
EC_KEY* pKey = EC_KEY_new_by_curve_name(nid);
|
||||
if(pKey == NULL) { return 0;}
|
||||
const EC_GROUP* pGroup = EC_KEY_get0_group(pKey);
|
||||
if(pGroup == NULL) { EC_KEY_free(pKey); return 0;}
|
||||
|
||||
int ret = EC_KEY_generate_key(pKey);
|
||||
if(ret == 0) { EC_KEY_free(pKey); return 0;}
|
||||
|
||||
const EC_POINT* pPoint = EC_KEY_get0_public_key(pKey);
|
||||
if(pPoint == NULL) { EC_KEY_free(pKey); return 0;}
|
||||
|
||||
size_t retSize = EC_POINT_point2oct(pGroup, pPoint, 4, (unsigned char *)buf, 64, 0);
|
||||
memcpy(pubKey, buf, retSize);
|
||||
|
||||
unsigned char* outPriKey = NULL;
|
||||
retSize = i2d_ECPrivateKey(pKey, &outPriKey);
|
||||
memcpy(priKey, outPriKey, retSize);
|
||||
free(outPriKey);
|
||||
|
||||
return retSize;
|
||||
}
|
||||
|
||||
int ComputerECCKeyMD5(char* pub, int pubLen, char* pri, int priLen, char* eccKey)
|
||||
{
|
||||
EC_KEY* pKey = NULL;
|
||||
d2i_ECPrivateKey(&pKey, (const unsigned char **)&pri, priLen);
|
||||
if(pKey == NULL) { return 0;}
|
||||
|
||||
char outBuf[64] = {0};
|
||||
const EC_GROUP* pGroup = EC_KEY_get0_group(pKey);
|
||||
if(pGroup == NULL) { EC_KEY_free(pKey); return 0;}
|
||||
EC_POINT* pPoint = EC_POINT_new(pGroup);
|
||||
if(pPoint == NULL) { EC_KEY_free(pKey); return 0;}
|
||||
int ret = EC_POINT_oct2point(pGroup, pPoint, (const unsigned char *)pub, pubLen, NULL);
|
||||
if(ret != 1) { EC_KEY_free(pKey); return 0;}
|
||||
int retLen = ECDH_compute_key(outBuf, 64, pPoint, pKey, NULL);
|
||||
if(retLen <= 0) { return 0;}
|
||||
MD5((const unsigned char *)outBuf, retLen, (unsigned char *)eccKey);
|
||||
|
||||
return retLen;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
import "C"
|
||||
import (
|
||||
"crypto/elliptic"
|
||||
"crypto/md5"
|
||||
"crypto/rand"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func getCharPointer(val []byte) *C.char {
|
||||
return (*C.char)(unsafe.Pointer(&val[0]))
|
||||
}
|
||||
|
||||
//GenerateEccKey GenerateEccKey2
|
||||
func GenerateEccKey() ([]byte, []byte) {
|
||||
pubKeyBuf := make([]byte, 57)
|
||||
priKeyBuf := make([]byte, 106)
|
||||
cPubKeyBuf := getCharPointer(pubKeyBuf)
|
||||
cPriKeyBuf := getCharPointer(priKeyBuf)
|
||||
//https://tools.ietf.org/html/rfc5480 Sect409k1.nid = 731
|
||||
C.GenerateECKey(713, cPubKeyBuf, cPriKeyBuf)
|
||||
return pubKeyBuf, priKeyBuf
|
||||
}
|
||||
|
||||
//ComputerECCKeyMD5 ComputerECCKeyMD52
|
||||
func ComputerECCKeyMD5(ecPubKey []byte, ecPriKey []byte) []byte {
|
||||
cEcPubKey := getCharPointer(ecPubKey)
|
||||
cEcPriKey := getCharPointer(ecPriKey)
|
||||
outAesKey := make([]byte, 16)
|
||||
cOutAesKey := getCharPointer(outAesKey)
|
||||
cPubKeyLen := C.int(len(ecPubKey))
|
||||
cPriKeyLen := C.int(len(ecPriKey))
|
||||
C.ComputerECCKeyMD5(cEcPubKey, cPubKeyLen, cEcPriKey, cPriKeyLen, cOutAesKey)
|
||||
|
||||
return outAesKey
|
||||
}
|
||||
|
||||
|
||||
//GenerateEccKey GenerateEccKey2
|
||||
func GenerateEccKey() ([]byte, []byte) {
|
||||
newEllipticECDH := NewEllipticECDH(elliptic.P224())
|
||||
priKeyBuf, pubKeyBuf, err := newEllipticECDH.GenerateKey(rand.Reader)
|
||||
if err != nil {
|
||||
return []byte{}, []byte{}
|
||||
}
|
||||
|
||||
return pubKeyBuf, priKeyBuf
|
||||
}
|
||||
|
||||
//ComputerECCKeyMD5 ComputerECCKeyMD52
|
||||
func ComputerECCKeyMD5(ecPubKey []byte, ecPriKey []byte) []byte {
|
||||
e := NewEllipticECDH(elliptic.P224())
|
||||
srvPubKey, ok := e.Unmarshal(ecPubKey)
|
||||
if !ok {
|
||||
return []byte{}
|
||||
}
|
||||
pwd, err := e.GenerateSharedSecret(ecPriKey, srvPubKey)
|
||||
if err != nil {
|
||||
return []byte{}
|
||||
}
|
||||
ctx := md5.New()
|
||||
_, _ = ctx.Write(pwd)
|
||||
return ctx.Sum(nil)
|
||||
}*/
|
||||
@@ -0,0 +1,81 @@
|
||||
package cecdh
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/elliptic"
|
||||
"io"
|
||||
"math/big"
|
||||
)
|
||||
|
||||
// ECDH 秘钥交换算法的主接口
|
||||
type ECDH interface {
|
||||
GenerateKey(io.Reader) ([]byte, []byte, error)
|
||||
Marshal(crypto.PublicKey) []byte
|
||||
Unmarshal([]byte) (crypto.PublicKey, bool)
|
||||
GenerateSharedSecret([]byte, crypto.PublicKey) ([]byte, error)
|
||||
}
|
||||
|
||||
type ellipticECDH struct {
|
||||
ECDH
|
||||
curve elliptic.Curve
|
||||
}
|
||||
|
||||
type ellipticPublicKey struct {
|
||||
elliptic.Curve
|
||||
X, Y *big.Int
|
||||
}
|
||||
|
||||
// NewEllipticECDH 指定一种椭圆曲线算法用于创建一个ECDH的实例
|
||||
// 关于椭圆曲线算法标准库里面实现了4种: 见crypto/elliptic
|
||||
func NewEllipticECDH(curve elliptic.Curve) ECDH {
|
||||
return &ellipticECDH{
|
||||
curve: curve,
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateKey 基于标准库的NIST椭圆曲线算法生成秘钥对
|
||||
func (e *ellipticECDH) GenerateKey(rand io.Reader) ([]byte, []byte, error) {
|
||||
var d []byte
|
||||
var x, y *big.Int
|
||||
var pub *ellipticPublicKey
|
||||
var err error
|
||||
d, x, y, err = elliptic.GenerateKey(e.curve, rand)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
pub = &ellipticPublicKey{
|
||||
Curve: e.curve,
|
||||
X: x,
|
||||
Y: y,
|
||||
}
|
||||
return d, e.Marshal(pub), nil
|
||||
}
|
||||
|
||||
// Marshal用于公钥的序列化
|
||||
func (e *ellipticECDH) Marshal(p crypto.PublicKey) []byte {
|
||||
pub := p.(*ellipticPublicKey)
|
||||
return elliptic.Marshal(e.curve, pub.X, pub.Y)
|
||||
}
|
||||
|
||||
// Unmarshal用于公钥的反序列化
|
||||
func (e *ellipticECDH) Unmarshal(data []byte) (crypto.PublicKey, bool) {
|
||||
var key *ellipticPublicKey
|
||||
var x, y *big.Int
|
||||
x, y = elliptic.Unmarshal(e.curve, data)
|
||||
if x == nil || y == nil {
|
||||
return key, false
|
||||
}
|
||||
key = &ellipticPublicKey{
|
||||
Curve: e.curve,
|
||||
X: x,
|
||||
Y: y,
|
||||
}
|
||||
return key, true
|
||||
}
|
||||
|
||||
// GenerateSharedSecret 通过自己的私钥和对方的公钥协商一个共享密码
|
||||
func (e *ellipticECDH) GenerateSharedSecret(privKey []byte, pubKey crypto.PublicKey) ([]byte, error) {
|
||||
pub := pubKey.(*ellipticPublicKey)
|
||||
x, _ := e.curve.ScalarMult(pub.X, pub.Y, privKey)
|
||||
return x.Bytes(), nil
|
||||
}
|
||||
Reference in New Issue
Block a user