ECC in OPEN SSL 2(operations)

来源:互联网 发布:钢材价格查询软件 编辑:程序博客网 时间:2024/05/17 02:10

Key pair generation:

    1, chooses a kind of Elliptic Curve. The OPEN provides 67 kinds of EC, and you can get the EC list by calling EC_get_builtin_curves();

    2, initial the group information, which defines the EC. EC_GROUP_new_by_curve_name(),EC_KEY_set_group()

    3, generate EC: EC_KEY_generate_key()

    Or you may generate the curves by calling EC_KEY_new_by_curve_name() directly Sample code:

BOOL generate_ECC_keypair (IN OUT EC_KEY **pKey, IN unsigned int nidIndex)

{

    EC_KEY *key = NULL;

    EC_builtin_curve *curves = NULL;

    int crv_len = 0;

    int nid = 0;  // curve id

    BOOL ok = TRUE;

 

    // get the number of EC

    crv_len = EC_get_builtin_curves(NULL, 0);

    if (nidIndex > crv_len) {

 

       ok = FALSE;

       goto err;

    }

 

    if ((curves = (EC_builtin_curve *)OPENSSL_malloc(sizeof(EC_builtin_curve) * crv_len)) == NULL) {

 

       ok = FALSE;

       goto err;

    }

 

    // get default EC list

    EC_get_builtin_curves(curves, crv_len);

 

    // choose a EC

    nid = curves[nidIndex].nid;

 

    // create the key pair

    if ((key = EC_KEY_new_by_curve_name(nid)) == NULL) {

 

       ok = FALSE;

       goto err;

    }

 

    if (!EC_KEY_generate_key(key)) {

 

       EC_KEY_free(key);

       ok = FALSE;

       goto err;

    }

 

    //don't have to check if pKey is NULL

    *pKey = key;

 

err:

    if (curves)

       OPENSSL_free(curves);

 

    return ok;

}

 

Sign and verify:

Just use ECDSA_sign() and ECDSA_verify(). Notes that signature length should be longer than ECDSA_size().

ecdsa_md, use SHA1 NID_ecdsa_with_SHA1.

sign the same data with the same EC key pair, the signature is different!

    Cause the EC algorithm can only be used for sign and verify, EC doesn’t support encrypt and decrypt. It’s different from RSA, when using RSA, the signatures from the same key pair and data are the same.

 

Key pair import and export:

We need to export two parts:

    1), the EC group, which include all the EC features,

    2), key information. And the private key contains the public key.

Here we introduce a struct to restore the information:

 

EC_KEY_check_key() can check both private key and public key.

 

Sample code

/*++

export and import two parts:

i.  parameters,

ii. private key

our own struct to restore EC key

{

    int iparaLen;

    unsigned char *parameters;

    int iPriKeyLen;

    unsigned char *bPriKeyBuf;

}

--*/

BOOL export_ECC_Privatekey(EC_KEY *pKey, unsigned char **buf, unsigned int *piBufLen)

{

    const EC_GROUP *group = NULL;

    unsigned char *bParameter= NULL;

    unsigned char *bPriKey= NULL;

    unsigned char *p; // pointer to buf

    unsigned int iParaSize = 0, iPriSize = 0;

    BOOL ok = TRUE;

 

    if (!EC_KEY_check_key(pKey))    return FALSE;

 

    // get all the length info

    iParaSize = i2d_ECParameters(pKey, NULL);

    if (!iParaSize)   return FALSE;

 

    iPriSize = i2d_ECPrivateKey(pKey, NULL);

    if (!iPriSize) {

 

       ok = FALSE;

       goto err;

    }

    *piBufLen = sizeof(int) * 2 + iParaSize + iPriSize;

 

    // get the pub key in ASN.1 form

    if (!i2d_ECParameters(pKey, &bParameter)) {

 

       ok = FALSE;

       goto err;

    }

 

    if (!i2d_ECPrivateKey(pKey, &bPriKey)) {

 

       ok = FALSE;

       goto err;

    }

 

    // allocate the memory for EC output

    if ((p = (unsigned char *)OPENSSL_malloc(*piBufLen)) == NULL) {

 

       ok = FALSE;

       goto err;

    }

    *buf = p;

 

    // pub key

    *(int *)p = iParaSize;

    p += sizeof(int);

    memcpy(p, bParameter, iParaSize);

    p += iParaSize;

 

    // pri key

    *(int *)p = iPriSize;

    p += sizeof(int);

    memcpy(p, bPriKey, iPriSize);

 

err:

    if (bParameter)   OPENSSL_free(bParameter);

    if (bPriKey)  OPENSSL_free(bPriKey);

 

    return ok;

}

 

BOOL import_ECC_Privatekey(EC_KEY **pKey, unsigned char *buf, unsigned int iBufLen)

{

    EC_KEY *key = NULL;

    unsigned char *p = buf;

    unsigned int iParaSize = 0, iPriSize = 0;

 

    if (NULL == buf)  return FALSE;

 

    // create the key

    if ((key = EC_KEY_new()) == NULL)  return FALSE;

 

    iParaSize = *(int *)p;

    p += sizeof(int);

 

    if (!d2i_ECParameters(&key, (const unsigned char **)&p, iParaSize))

       return FALSE;

 

    iPriSize = *(int *)p;

    p += sizeof(int);

 

    if (!d2i_ECPrivateKey(&key, (const unsigned char **)&p, iPriSize))

       return FALSE;

 

    *pKey = key;

 

    return TRUE;

}

 

原创粉丝点击