// KeyDecrypt decrypts the encrypted key using ECDH-ES func (kw EcdhesKeyWrapDecrypt) KeyDecrypt(enckey []byte) ([]byte, error) { var keysize uint32 switch kw.algorithm { case jwa.ECDH_ES_A128KW: keysize = 16 case jwa.ECDH_ES_A192KW: keysize = 24 case jwa.ECDH_ES_A256KW: keysize = 32 default: return nil, ErrUnsupportedAlgorithm } privkey := kw.privkey pubkey := kw.pubkey pubinfo := make([]byte, 4) binary.BigEndian.PutUint32(pubinfo, keysize*8) z, _ := privkey.PublicKey.Curve.ScalarMult(pubkey.X, pubkey.Y, privkey.D.Bytes()) kdf := concatkdf.New(crypto.SHA256, []byte(kw.algorithm.String()), z.Bytes(), kw.apu, kw.apv, pubinfo, []byte{}) kek := make([]byte, keysize) kdf.Read(kek) block, err := aes.NewCipher(kek) if err != nil { return nil, err } return keyunwrap(block, enckey) }
// KeyGenerate generates new keys using ECDH-ES func (g EcdhesKeyGenerate) KeyGenerate() (ByteSource, error) { priv, err := ecdsa.GenerateKey(g.pubkey.Curve, rand.Reader) if err != nil { return nil, err } pubinfo := make([]byte, 4) binary.BigEndian.PutUint32(pubinfo, uint32(g.keysize)*8) z, _ := priv.PublicKey.Curve.ScalarMult(g.pubkey.X, g.pubkey.Y, priv.D.Bytes()) kdf := concatkdf.New(crypto.SHA256, []byte(g.algorithm.String()), z.Bytes(), []byte{}, []byte{}, pubinfo, []byte{}) kek := make([]byte, g.keysize) kdf.Read(kek) return ByteWithECPrivateKey{ PrivateKey: priv, ByteKey: ByteKey(kek), }, nil }