GO加密函数封装

This commit is contained in:
songguangy
2018-11-05 18:40:36 +08:00
parent fa95031ca7
commit 99f9ca4d1e
6 changed files with 622 additions and 25 deletions

83
.idea/workspace.xml generated
View File

@@ -2,10 +2,7 @@
<project version="4">
<component name="ChangeListManager">
<list default="true" id="879b126a-5488-4e29-a4e1-3a8936e89a2d" name="默认的" comment="">
<change afterPath="$PROJECT_DIR$/.idea/vcs.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/AES_CBC.go" beforeDir="false" afterPath="$PROJECT_DIR$/AES_CBC.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DES_CBC.go" beforeDir="false" afterPath="$PROJECT_DIR$/DES_CBC.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/RsaCrypt.go" beforeDir="false" afterPath="$PROJECT_DIR$/RsaCrypt.go" afterDir="false" />
<change beforePath="$PROJECT_DIR$/GetECCKey.go" beforeDir="false" afterPath="$PROJECT_DIR$/GetECCKey.go" afterDir="false" />
</list>
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
<option name="TRACKING_ENABLED" value="true" />
@@ -15,12 +12,24 @@
<option name="LAST_RESOLUTION" value="IGNORE" />
</component>
<component name="FileEditorManager">
<leaf>
<file leaf-file-name="EccSign.go" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/EccSign.go">
<leaf SIDE_TABS_SIZE_LIMIT_KEY="375">
<file leaf-file-name="ecies.go" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/ecies.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="837">
<caret line="82" lean-forward="true" selection-start-line="82" selection-end-line="82" />
<state relative-caret-position="7506">
<caret line="391" column="5" selection-start-line="391" selection-start-column="5" selection-end-line="391" selection-end-column="5" />
</state>
</provider>
</entry>
</file>
<file leaf-file-name="EccCrypt.go" pinned="false" current-in-tab="false">
<entry file="file://$PROJECT_DIR$/EccCrypt.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-891">
<caret line="39" column="35" selection-start-line="39" selection-start-column="35" selection-end-line="39" selection-end-column="35" />
<folding>
<element signature="e#15#153#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
@@ -40,6 +49,8 @@
<option value="$PROJECT_DIR$/DES_CBC.go" />
<option value="$PROJECT_DIR$/GetECCKey.go" />
<option value="$PROJECT_DIR$/EccSign.go" />
<option value="$PROJECT_DIR$/ecies.go" />
<option value="$PROJECT_DIR$/EccCrypt.go" />
</list>
</option>
</component>
@@ -66,7 +77,6 @@
<foldersAlwaysOnTop value="true" />
</navigator>
<panes>
<pane id="Scope" />
<pane id="ProjectPane">
<subPane>
<expand>
@@ -78,6 +88,7 @@
<select />
</subPane>
</pane>
<pane id="Scope" />
</panes>
</component>
<component name="PropertiesComponent">
@@ -103,7 +114,7 @@
<frame x="-8" y="-8" width="1456" height="886" extended-state="6" />
<editor active="true" />
<layout>
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.21748555" />
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.22182082" />
<window_info anchor="bottom" id="TODO" order="6" />
<window_info anchor="bottom" id="调试" order="7" />
<window_info anchor="bottom" id="Event Log" order="7" side_tool="true" />
@@ -111,8 +122,8 @@
<window_info anchor="bottom" id="Database Changes" order="7" show_stripe_button="false" />
<window_info anchor="bottom" id="Version Control" order="7" show_stripe_button="false" />
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
<window_info anchor="bottom" id="Terminal" order="7" />
<window_info anchor="bottom" id="运行" order="7" />
<window_info anchor="bottom" id="Terminal" order="7" />
<window_info id="Favorites" order="2" side_tool="true" />
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
@@ -132,6 +143,13 @@
<option name="myLimit" value="2678400000" />
</component>
<component name="editorHistoryManager">
<entry file="file://$PROJECT_DIR$/EccSign.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1971">
<caret line="82" lean-forward="true" selection-start-line="82" selection-end-line="82" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/GetRsakey.go">
<provider selected="true" editor-type-id="text-editor" />
</entry>
@@ -160,16 +178,6 @@
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/AES_CBC.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="1807">
<caret line="83" column="9" lean-forward="true" selection-start-line="83" selection-start-column="9" selection-end-line="83" selection-end-column="9" />
<folding>
<element signature="e#19#87#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/RsaCrypt.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-162">
@@ -199,8 +207,35 @@
</entry>
<entry file="file://$PROJECT_DIR$/EccSign.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="837">
<caret line="82" lean-forward="true" selection-start-line="82" selection-end-line="82" />
<state relative-caret-position="1566">
<caret line="67" column="18" selection-start-line="67" selection-start-column="18" selection-end-line="67" selection-end-column="18" />
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/AES_CBC.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="592">
<caret line="83" column="9" lean-forward="true" selection-start-line="83" selection-start-column="9" selection-end-line="83" selection-end-column="9" />
<folding>
<element signature="e#19#87#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/EccCrypt.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="-891">
<caret line="39" column="35" selection-start-line="39" selection-start-column="35" selection-end-line="39" selection-end-column="35" />
<folding>
<element signature="e#15#153#0" expanded="true" />
</folding>
</state>
</provider>
</entry>
<entry file="file://$PROJECT_DIR$/ecies.go">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="7506">
<caret line="391" column="5" selection-start-line="391" selection-start-column="5" selection-end-line="391" selection-end-column="5" />
</state>
</provider>
</entry>

92
EccCrypt.go Normal file
View File

@@ -0,0 +1,92 @@
package wmgocrypt
import (
"log"
"crypto/rand"
"encoding/pem"
"runtime"
"crypto/x509"
"crypto/ecdsa"
)
/*
@Time : 2018/11/4 16:43
@Author : wuman
@File : EccCrypt
@Software: GoLand
*/
func init(){
log.SetFlags(log.Ldate|log.Lshortfile)
} //处理日志的格式
//Ecc椭圆曲线的公钥加密如果要解密对应着私钥解密
/*func EccEnCrypt(plainText []byte,prv2 *ecies.PrivateKey)(crypText []byte,err error){
ct, err := ecies.Encrypt(rand.Reader, &prv2.PublicKey, plainText, nil, nil)
return ct, err
}
//直接解密
func EccDeCrypt(cryptText []byte,prv2 *ecies.PrivateKey) ([]byte, error) {
pt, err := prv2.Decrypt(cryptText, nil, nil)
return pt, err
}*/
//传入公钥和明文用来加密
func EccPublicEncrypt(plainText []byte,key []byte)( cryptText []byte,err error){ //用私钥解密
//1. pem 解码
block, _:= pem.Decode(key)
//防止用户传的密钥不正确导致panic,这里恢复程序并打印错误
defer func(){
if err:=recover();err!=nil{
switch err.(type){
case runtime.Error:
log.Println("runtime err:",err,"请检查密钥是否正确")
default:
log.Println("error:",err)
}
}
}()
//2. block中的Bytes是x509编码的内容, x509解码
tempPublicKey, _ := x509.ParsePKIXPublicKey(block.Bytes)
//解码得到ecdsa包中的私钥
//类型断言
publicKey1:=tempPublicKey.(*ecdsa.PublicKey)
//转换为以太坊包中的ecies包中的私钥
publicKey:=ImportECDSAPublic(publicKey1)
//用私钥来解密密文
crypttext,err:=Encrypt(rand.Reader, publicKey, plainText, nil, nil)
return crypttext,err
}
//传入私钥和明文用来解密
func EccPrivateDeCrypt(cryptText []byte,key []byte)( msg []byte,err error){ //用私钥解密
//1. pem 解码
block, _:= pem.Decode(key)
//防止用户传的密钥不正确导致panic,这里恢复程序并打印错误
defer func(){
if err:=recover();err!=nil{
switch err.(type){
case runtime.Error:
log.Println("runtime err:",err,"请检查密钥是否正确")
default:
log.Println("error:",err)
}
}
}()
//2. block中的Bytes是x509编码的内容, x509解码
tempPrivateKey, _ := x509.ParseECPrivateKey(block.Bytes)
//解码得到ecdsa包中的私钥
//转换为以太坊包中的ecies包中的私钥
privateKey:=ImportECDSA(tempPrivateKey)
//用私钥来解密密文
plainText,err:=privateKey.Decrypt(cryptText,nil,nil)
return plainText,err
}

View File

@@ -22,7 +22,7 @@ func init(){
//ECC椭圆曲线密钥对生成
func GetEccKey(){
//1.生成密钥对
privateKey, _ := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
privateKey, _ := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
//2.将密钥保存到相关的文件中
// x509标准编码

View File

@@ -297,6 +297,52 @@ W/fnOWXyXQ7DB16jMSQ=
> ECC椭圆曲线技术应用广泛目前我国居民身份证数字签名技术就是使用的ECC虚拟货币比特币和以太坊中也使用了ECC技术后面我们会把ECC加密的方法也实现好。
#### 4.3 ECC用作加密十用非对称加密是用公钥来加密私钥来解密的由于GO标准包中没有实现ECC加密的接口只实现了ECC数字签名的接口我们找了以太坊源码中的ECC加密的使用方法稍加改造了一下拿过来用了在这里调用了以太坊加密包里面的接口来实现ECC加密的方法我们把加密的东西二次封装了一下下载包后就可以直接使用
首先还是先得到公钥和私钥
```
func main(){
wmgocrypt.GetEccKey()
} //这里我们得到的密钥是通过P256曲线得到的由于之前验证用别的曲线调用以太坊接口会报错
```
然后就可以快速使用了
```
func main(){
plainText:=[]byte("窗前明月光,疑是地上霜,ECC加密解密")
//这里传入的私钥和公钥是要用GetECCKey里面得到的私钥和公钥如果自己封装的话
// 获取密钥时传入的第一个参数是要用这条曲线elliptic.P256(),如果用别的会报无效公钥错误,
// 例如用P521()这条曲线
privateKey:=[]byte(`-----BEGIN WUMAN ECC PRIVATE KEY-----
MHcCAQEEIKozbXD9G6bGPJ26cCAfEdLrqAe697F8SiLRMdqxzNQ5oAoGCCqGSM49
AwEHoUQDQgAEk3/hltyR0r0J2Wkkhi4HaREJXS1vFooGpsKCbLvrdUW4peVIwKEW
+yC3/g2X7Q2A8ftJlYv2X4kDU180GhIQpA==
-----END WUMAN ECC PRIVATE KEY-----
`)
publicKey:=[]byte(`-----BEGIN WUMAN ECC PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEk3/hltyR0r0J2Wkkhi4HaREJXS1v
FooGpsKCbLvrdUW4peVIwKEW+yC3/g2X7Q2A8ftJlYv2X4kDU180GhIQpA==
-----END WUMAN ECC PUBLIC KEY-----
`)
cryptText,_:=wmgocrypt.EccPublicEncrypt(plainText,publicKey)
fmt.Println("ECC传入公钥加密的密文为",hex.EncodeToString(cryptText))
msg,err:=wmgocrypt.EccPrivateDeCrypt(cryptText,privateKey)
if err!=nil{
fmt.Println(err)
}
fmt.Println("ECC传入私钥解密后的明文为",string(msg))
}
```
![](image/16.png)
## 5.附带的哈希函数sha256和sha512使用非常简单
#### 5.1 sh256的快速使用

424
ecies.go Normal file
View File

@@ -0,0 +1,424 @@
// Copyright (c) 2013 Kyle Isom <kyle@tyrfingr.is>
// Copyright (c) 2012 The Go Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
package wmgocrypt
import (
"crypto/cipher"
"crypto/ecdsa"
"crypto/elliptic"
"crypto/hmac"
"crypto/subtle"
"fmt"
"hash"
"io"
"math/big"
"crypto"
"crypto/sha256"
"crypto/aes"
"crypto/sha512"
)
var (
ErrImport = fmt.Errorf("ecies: failed to import key")
ErrInvalidCurve = fmt.Errorf("ecies: invalid elliptic curve")
ErrInvalidParams = fmt.Errorf("ecies: invalid ECIES parameters")
ErrInvalidPublicKey = fmt.Errorf("ecies: invalid public key")
ErrSharedKeyIsPointAtInfinity = fmt.Errorf("ecies: shared key is point at infinity")
ErrSharedKeyTooBig = fmt.Errorf("ecies: shared key params are too big")
ErrUnsupportedECIESParameters = fmt.Errorf("ecies: unsupported ECIES parameters")
)
// PublicKey is a representation of an elliptic curve public key.
type PublicKey struct {
X *big.Int
Y *big.Int
elliptic.Curve
Params *ECIESParams
}
// Export an ECIES public key as an ECDSA public key.
func (pub *PublicKey) ExportECDSA() *ecdsa.PublicKey {
return &ecdsa.PublicKey{Curve: pub.Curve, X: pub.X, Y: pub.Y}
}
// Import an ECDSA public key as an ECIES public key.
func ImportECDSAPublic(pub *ecdsa.PublicKey) *PublicKey {
return &PublicKey{
X: pub.X,
Y: pub.Y,
Curve: pub.Curve,
Params: ParamsFromCurve(pub.Curve),
}
}
// PrivateKey is a representation of an elliptic curve private key.
type PrivateKey struct {
PublicKey
D *big.Int
}
// Export an ECIES private key as an ECDSA private key.
func (prv *PrivateKey) ExportECDSA() *ecdsa.PrivateKey {
pub := &prv.PublicKey
pubECDSA := pub.ExportECDSA()
return &ecdsa.PrivateKey{PublicKey: *pubECDSA, D: prv.D}
}
// Import an ECDSA private key as an ECIES private key.
func ImportECDSA(prv *ecdsa.PrivateKey) *PrivateKey {
pub := ImportECDSAPublic(&prv.PublicKey)
return &PrivateKey{*pub, prv.D}
}
// Generate an elliptic curve public / private keypair. If params is nil,
// the recommended default parameters for the key will be chosen.
func GenerateKey(rand io.Reader, curve elliptic.Curve, params *ECIESParams) (prv *PrivateKey, err error) {
pb, x, y, err := elliptic.GenerateKey(curve, rand)
if err != nil {
return
}
prv = new(PrivateKey)
prv.PublicKey.X = x
prv.PublicKey.Y = y
prv.PublicKey.Curve = curve
prv.D = new(big.Int).SetBytes(pb)
if params == nil {
params = ParamsFromCurve(curve)
}
prv.PublicKey.Params = params
return
}
// MaxSharedKeyLength returns the maximum length of the shared key the
// public key can produce.
func MaxSharedKeyLength(pub *PublicKey) int {
return (pub.Curve.Params().BitSize + 7) / 8
}
// ECDH key agreement method used to establish secret keys for encryption.
func (prv *PrivateKey) GenerateShared(pub *PublicKey, skLen, macLen int) (sk []byte, err error) {
if prv.PublicKey.Curve != pub.Curve {
return nil, ErrInvalidCurve
}
if skLen+macLen > MaxSharedKeyLength(pub) {
return nil, ErrSharedKeyTooBig
}
x, _ := pub.Curve.ScalarMult(pub.X, pub.Y, prv.D.Bytes())
if x == nil {
return nil, ErrSharedKeyIsPointAtInfinity
}
sk = make([]byte, skLen+macLen)
skBytes := x.Bytes()
copy(sk[len(sk)-len(skBytes):], skBytes)
return sk, nil
}
var (
ErrKeyDataTooLong = fmt.Errorf("ecies: can't supply requested key data")
ErrSharedTooLong = fmt.Errorf("ecies: shared secret is too long")
ErrInvalidMessage = fmt.Errorf("ecies: invalid message")
)
var (
big2To32 = new(big.Int).Exp(big.NewInt(2), big.NewInt(32), nil)
big2To32M1 = new(big.Int).Sub(big2To32, big.NewInt(1))
)
func incCounter(ctr []byte) {
if ctr[3]++; ctr[3] != 0 {
return
}
if ctr[2]++; ctr[2] != 0 {
return
}
if ctr[1]++; ctr[1] != 0 {
return
}
if ctr[0]++; ctr[0] != 0 {
return
}
}
// NIST SP 800-56 Concatenation Key Derivation Function (see section 5.8.1).
func concatKDF(hash hash.Hash, z, s1 []byte, kdLen int) (k []byte, err error) {
if s1 == nil {
s1 = make([]byte, 0)
}
reps := ((kdLen + 7) * 8) / (hash.BlockSize() * 8)
if big.NewInt(int64(reps)).Cmp(big2To32M1) > 0 {
fmt.Println(big2To32M1)
return nil, ErrKeyDataTooLong
}
counter := []byte{0, 0, 0, 1}
k = make([]byte, 0)
for i := 0; i <= reps; i++ {
hash.Write(counter)
hash.Write(z)
hash.Write(s1)
k = append(k, hash.Sum(nil)...)
hash.Reset()
incCounter(counter)
}
k = k[:kdLen]
return
}
// messageTag computes the MAC of a message (called the tag) as per
// SEC 1, 3.5.
func messageTag(hash func() hash.Hash, km, msg, shared []byte) []byte {
mac := hmac.New(hash, km)
mac.Write(msg)
mac.Write(shared)
tag := mac.Sum(nil)
return tag
}
// Generate an initialisation vector for CTR mode.
func generateIV(params *ECIESParams, rand io.Reader) (iv []byte, err error) {
iv = make([]byte, params.BlockSize)
_, err = io.ReadFull(rand, iv)
return
}
// symEncrypt carries out CTR encryption using the block cipher specified in the
// parameters.
func symEncrypt(rand io.Reader, params *ECIESParams, key, m []byte) (ct []byte, err error) {
c, err := params.Cipher(key)
if err != nil {
return
}
iv, err := generateIV(params, rand)
if err != nil {
return
}
ctr := cipher.NewCTR(c, iv)
ct = make([]byte, len(m)+params.BlockSize)
copy(ct, iv)
ctr.XORKeyStream(ct[params.BlockSize:], m)
return
}
// symDecrypt carries out CTR decryption using the block cipher specified in
// the parameters
func symDecrypt(params *ECIESParams, key, ct []byte) (m []byte, err error) {
c, err := params.Cipher(key)
if err != nil {
return
}
ctr := cipher.NewCTR(c, ct[:params.BlockSize])
m = make([]byte, len(ct)-params.BlockSize)
ctr.XORKeyStream(m, ct[params.BlockSize:])
return
}
// Encrypt encrypts a message using ECIES as specified in SEC 1, 5.1.
//
// s1 and s2 contain shared information that is not part of the resulting
// ciphertext. s1 is fed into key derivation, s2 is fed into the MAC. If the
// shared information parameters aren't being used, they should be nil.
func Encrypt(rand io.Reader, pub *PublicKey, m, s1, s2 []byte) (ct []byte, err error) {
params := pub.Params
if params == nil {
if params = ParamsFromCurve(pub.Curve); params == nil {
err = ErrUnsupportedECIESParameters
return
}
}
R, err := GenerateKey(rand, pub.Curve, params)
if err != nil {
return
}
hash := params.Hash()
z, err := R.GenerateShared(pub, params.KeyLen, params.KeyLen)
if err != nil {
return
}
K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
if err != nil {
return
}
Ke := K[:params.KeyLen]
Km := K[params.KeyLen:]
hash.Write(Km)
Km = hash.Sum(nil)
hash.Reset()
em, err := symEncrypt(rand, params, Ke, m)
if err != nil || len(em) <= params.BlockSize {
return
}
d := messageTag(params.Hash, Km, em, s2)
Rb := elliptic.Marshal(pub.Curve, R.PublicKey.X, R.PublicKey.Y)
ct = make([]byte, len(Rb)+len(em)+len(d))
copy(ct, Rb)
copy(ct[len(Rb):], em)
copy(ct[len(Rb)+len(em):], d)
return
}
// Decrypt decrypts an ECIES ciphertext.
func (prv *PrivateKey) Decrypt(c, s1, s2 []byte) (m []byte, err error) {
if len(c) == 0 {
return nil, ErrInvalidMessage
}
params := prv.PublicKey.Params
if params == nil {
if params = ParamsFromCurve(prv.PublicKey.Curve); params == nil {
err = ErrUnsupportedECIESParameters
return
}
}
hash := params.Hash()
var (
rLen int
hLen int = hash.Size()
mStart int
mEnd int
)
switch c[0] {
case 2, 3, 4:
rLen = (prv.PublicKey.Curve.Params().BitSize + 7) / 4
if len(c) < (rLen + hLen + 1) {
err = ErrInvalidMessage
return
}
default:
err = ErrInvalidPublicKey
return
}
mStart = rLen
mEnd = len(c) - hLen
R := new(PublicKey)
R.Curve = prv.PublicKey.Curve
R.X, R.Y = elliptic.Unmarshal(R.Curve, c[:rLen])
if R.X == nil {
err = ErrInvalidPublicKey
return
}
if !R.Curve.IsOnCurve(R.X, R.Y) {
err = ErrInvalidCurve
return
}
z, err := prv.GenerateShared(R, params.KeyLen, params.KeyLen)
if err != nil {
return
}
K, err := concatKDF(hash, z, s1, params.KeyLen+params.KeyLen)
if err != nil {
return
}
Ke := K[:params.KeyLen]
Km := K[params.KeyLen:]
hash.Write(Km)
Km = hash.Sum(nil)
hash.Reset()
d := messageTag(params.Hash, Km, c[mStart:mEnd], s2)
if subtle.ConstantTimeCompare(c[mEnd:], d) != 1 {
err = ErrInvalidMessage
return
}
m, err = symDecrypt(params, Ke, c[mStart:mEnd])
return
}
//以下为从以太坊源码/crypt/ecies/params.go中截取过来
func ParamsFromCurve(curve elliptic.Curve) (params *ECIESParams) {
return paramsFromCurve[curve]
}
var paramsFromCurve = map[elliptic.Curve]*ECIESParams{
//ethcrypto.S256(): ECIES_AES128_SHA256,
elliptic.P256(): ECIES_AES128_SHA256,
elliptic.P384(): ECIES_AES256_SHA384,
elliptic.P521(): ECIES_AES256_SHA512,
}
var (
ECIES_AES128_SHA256 = &ECIESParams{
Hash: sha256.New,
hashAlgo: crypto.SHA256,
Cipher: aes.NewCipher,
BlockSize: aes.BlockSize,
KeyLen: 16,
}
ECIES_AES256_SHA256 = &ECIESParams{
Hash: sha256.New,
hashAlgo: crypto.SHA256,
Cipher: aes.NewCipher,
BlockSize: aes.BlockSize,
KeyLen: 32,
}
ECIES_AES256_SHA384 = &ECIESParams{
Hash: sha512.New384,
hashAlgo: crypto.SHA384,
Cipher: aes.NewCipher,
BlockSize: aes.BlockSize,
KeyLen: 32,
}
ECIES_AES256_SHA512 = &ECIESParams{
Hash: sha512.New,
hashAlgo: crypto.SHA512,
Cipher: aes.NewCipher,
BlockSize: aes.BlockSize,
KeyLen: 32,
}
)
type ECIESParams struct {
Hash func() hash.Hash // hash function
hashAlgo crypto.Hash
Cipher func([]byte) (cipher.Block, error) // symmetric cipher
BlockSize int // block size of symmetric cipher
KeyLen int // length of symmetric key
}

BIN
image/16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB