Alexander Mikheev
Alexander Mikheev

Reputation: 149

How to set up a keyvault using secp256k1 algorithm in GCP?

I have to set up a keyvault using secp256k1 algorithm as a Google Cloud Platform service and don't know where to start.

I checked available options and found only Elliptic Curve P-256 - SHA256 digest support. Is this the same as secp256k1?

Upvotes: 0

Views: 1095

Answers (1)

fbmch
fbmch

Reputation: 721

If what you mean by your first sentence is having the analogous (at least partially) service of Key Vault with Google Cloud Platform (with this being Cloud Key Management Service aka KMS) then the answer is no.

While for Azure's Key Vault the elliptic curve SECP256K1 is available, at the moment for Cloud KMS the only elliptic curves available are P-256 and P-384.

The P-256 and SECP256K1 curves are not the same and, as of now, P-256 is defined in FIPS-186-4 and SECP256K1 in Standards for Efficient Cryptography Version 2.

Anyways, to back all of this, you can run the following experiment.

Create a ASYMMETRIC_SIGN purpose key with Cloud SDK (see how-to):

keyring=keyring0
key=key0
location=US
gcloud kms keyrings create $keyring --location=$location
gcloud kms keys create $key --location $location --keyring $keyring --purpose asymmetric-signing --default-algorithm ec-sign-p256-sha256 --protection-level software

Sign a message and import the public key of the previously generated (KMS-generated that is) key pair.

message=message
signature=message.sig
echo $(date):$(uname -a) > $message
gcloud kms asymmetric-sign --keyring=$keyring --key=$key --location=$location --input-file=$message --signature-file=$signature --digest-algorithm=sha256 --version=1
gcloud kms keys versions get-public-key 1 --location=$location --keyring=$keyring --key=$key --output-file=./$keyring-$key.pub

Now you could verify the signature it with openssl dgst -verify $keyring-$key.pub -signature $signature $message but you won't get information about the elliptic curve used to generate the key pair of which the secret key was used to do the signing.

To get that information, we could install a Python third-party library:

virtualenv --python=/usr/bin/python3 ecdsa
cd ecdsa
source bin/activate
pip install ecdsa

And run the following command to verify the signature and see the curve used by KMS when the signing algorithm ec-sign-p256-sha256 was chosen:

python3 -c """
from pathlib import Path
import hashlib
from ecdsa import VerifyingKey, BadSignatureError

publickey = Path('$keyring-$key.pub')
signature = Path('$signature')
message = Path('$message')

def read_signature(signature):
    '''
    workaround for https://github.com/warner/python-ecdsa/issues/67
    more background on why's that in https://tools.ietf.org/html/rfc5652
    '''
    LEN = 64
    LENHALF = LEN//2
    with signature.open('rb') as fp:
        sig = fp.read()

    offset = 4 if sig[4] else 5
    slice_s, slice_r =  slice(offset, offset + LENHALF), slice(-LENHALF, len(sig))   
    s,r = sig[slice_s], sig[slice_r]
    return s + r

def verify(publickey, signature, message):

    with publickey.open() as pkfp, message.open('br') as messagefp:
        vk = VerifyingKey.from_pem(pkfp.read())
        try:
            print('Verifying with public key associated with curve', repr(vk.curve.name))
            vk.verify(read_signature(signature), messagefp.read(), hashfunc=hashlib.sha256)
            print('Verify Success')
        except BadSignatureError:
            print('Verify Failure')

verify(publickey, signature, message)
"""

To hammer the point home of the elliptic curve used in KMS in this example being NIST's P-256 and its parameter differences with SECP256K1, check out the following snippet:

python3 -c """
from collections import namedtuple 
from operator import attrgetter
from ecdsa import NIST256p, SECP256k1

sextuple = namedtuple('T', 'p, a, b, G, n, h')

ag_curve = attrgetter(*('curve._CurveFp__'+c for c in 'abp'))
ag_generator = attrgetter(*('generator._Point__'+c for c in 'x y order'.split()))

def make_sextuple(curve, h=1):
    n, G_x, G_y = ag_generator(curve)
    return sextuple(*ag_curve(curve), n=n, G=(G_x, G_y), h=h)

T_NIST256p = make_sextuple(NIST256p)
T_SECP256k1 = make_sextuple(SECP256k1)

if T_NIST256p != T_SECP256k1:
    for k in sextuple._fields:
        ag_k = attrgetter(k)
        v0, v1 = ag_k(T_NIST256p), ag_k(T_SECP256k1)
        if v0 != v1:
            print('Different values for parameter ', k,)
            print(v0)
            print(v1)
"""

Upvotes: 2

Related Questions