1. 列出所有椭圆曲线

# openssl ecparam -list_curves  
secp112r1 : SECG/WTLS curve over a 112 bit prime field  
  secp112r2 : SECG curve over a 112 bit prime field  
  secp128r1 : SECG curve over a 128 bit prime field  
  secp128r2 : SECG curve over a 128 bit prime field  
  secp160k1 : SECG curve over a 160 bit prime field  
  secp160r1 : SECG curve over a 160 bit prime field  
  secp160r2 : SECG/WTLS curve over a 160 bit prime field  
  secp192k1 : SECG curve over a 192 bit prime field  
  secp224k1 : SECG curve over a 224 bit prime field  
  secp224r1 : NIST/SECG curve over a 224 bit prime field  
  secp256k1 : SECG curve over a 256 bit prime field  
  secp384r1 : NIST/SECG curve over a 384 bit prime field  
  secp521r1 : NIST/SECG curve over a 521 bit prime field  
  prime192v1: NIST/X9.62/SECG curve over a 192 bit prime field  
  prime192v2: X9.62 curve over a 192 bit prime field  
  prime192v3: X9.62 curve over a 192 bit prime field  
  prime239v1: X9.62 curve over a 239 bit prime field  
  prime239v2: X9.62 curve over a 239 bit prime field  
  prime239v3: X9.62 curve over a 239 bit prime field  
  prime256v1: X9.62/SECG curve over a 256 bit prime field  
  sect113r1 : SECG curve over a 113 bit binary field  
  sect113r2 : SECG curve over a 113 bit binary field  
  sect131r1 : SECG/WTLS curve over a 131 bit binary field  
  sect131r2 : SECG curve over a 131 bit binary field  
  sect163k1 : NIST/SECG/WTLS curve over a 163 bit binary field  
  sect163r1 : SECG curve over a 163 bit binary field  
  sect163r2 : NIST/SECG curve over a 163 bit binary field  
  sect193r1 : SECG curve over a 193 bit binary field  
  sect193r2 : SECG curve over a 193 bit binary field  
  sect233k1 : NIST/SECG/WTLS curve over a 233 bit binary field  
  sect233r1 : NIST/SECG/WTLS curve over a 233 bit binary field  
  sect239k1 : SECG curve over a 239 bit binary field  
  sect283k1 : NIST/SECG curve over a 283 bit binary field  
  sect283r1 : NIST/SECG curve over a 283 bit binary field  
  sect409k1 : NIST/SECG curve over a 409 bit binary field  
  sect409r1 : NIST/SECG curve over a 409 bit binary field  
  sect571k1 : NIST/SECG curve over a 571 bit binary field  
  sect571r1 : NIST/SECG curve over a 571 bit binary field  
  c2pnb163v1: X9.62 curve over a 163 bit binary field  
  c2pnb163v2: X9.62 curve over a 163 bit binary field  
  c2pnb163v3: X9.62 curve over a 163 bit binary field  
  c2pnb176v1: X9.62 curve over a 176 bit binary field  
  c2tnb191v1: X9.62 curve over a 191 bit binary field  
  c2tnb191v2: X9.62 curve over a 191 bit binary field  
  c2tnb191v3: X9.62 curve over a 191 bit binary field  
  c2pnb208w1: X9.62 curve over a 208 bit binary field  
  c2tnb239v1: X9.62 curve over a 239 bit binary field  
  c2tnb239v2: X9.62 curve over a 239 bit binary field  
  c2tnb239v3: X9.62 curve over a 239 bit binary field  
  c2pnb272w1: X9.62 curve over a 272 bit binary field  
  c2pnb304w1: X9.62 curve over a 304 bit binary field  
  c2tnb359v1: X9.62 curve over a 359 bit binary field  
  c2pnb368w1: X9.62 curve over a 368 bit binary field  
  c2tnb431r1: X9.62 curve over a 431 bit binary field  
  wap-wsg-idm-ecid-wtls1: WTLS curve over a 113 bit binary field  
  wap-wsg-idm-ecid-wtls3: NIST/SECG/WTLS curve over a 163 bit binary field  
  wap-wsg-idm-ecid-wtls4: SECG curve over a 113 bit binary field  
  wap-wsg-idm-ecid-wtls5: X9.62 curve over a 163 bit binary field  
  wap-wsg-idm-ecid-wtls6: SECG/WTLS curve over a 112 bit prime field  
  wap-wsg-idm-ecid-wtls7: SECG/WTLS curve over a 160 bit prime field  
  wap-wsg-idm-ecid-wtls8: WTLS curve over a 112 bit prime field  
  wap-wsg-idm-ecid-wtls9: WTLS curve over a 160 bit prime field  
  wap-wsg-idm-ecid-wtls10: NIST/SECG/WTLS curve over a 233 bit binary field  
  wap-wsg-idm-ecid-wtls11: NIST/SECG/WTLS curve over a 233 bit binary field  
  wap-wsg-idm-ecid-wtls12: WTLS curvs over a 224 bit prime field  
  Oakley-EC2N-3:  
	IPSec/IKE/Oakley curve #3 over a 155 bit binary field.  
	Not suitable for ECDSA.  
	Questionable extension field!  
  Oakley-EC2N-4:  
	IPSec/IKE/Oakley curve #4 over a 185 bit binary field.  
	Not suitable for ECDSA.  
	Questionable extension field!  
  brainpoolP160r1: RFC 5639 curve over a 160 bit prime field  
  brainpoolP160t1: RFC 5639 curve over a 160 bit prime field  
  brainpoolP192r1: RFC 5639 curve over a 192 bit prime field  
  brainpoolP192t1: RFC 5639 curve over a 192 bit prime field  
  brainpoolP224r1: RFC 5639 curve over a 224 bit prime field  
  brainpoolP224t1: RFC 5639 curve over a 224 bit prime field  
  brainpoolP256r1: RFC 5639 curve over a 256 bit prime field  
  brainpoolP256t1: RFC 5639 curve over a 256 bit prime field  
  brainpoolP320r1: RFC 5639 curve over a 320 bit prime field  
  brainpoolP320t1: RFC 5639 curve over a 320 bit prime field  
  brainpoolP384r1: RFC 5639 curve over a 384 bit prime field
  brainpoolP384t1: RFC 5639 curve over a 384 bit prime field
  brainpoolP512r1: RFC 5639 curve over a 512 bit prime field  
  brainpoolP512t1: RFC 5639 curve over a 512 bit prime field  

2. 生成私钥参数

# openssl ecparam -name secp256k1 -genkey -out ec_private_key.pem  
# cat ec_private_key.pem  
  -----BEGIN EC PARAMETERS-----  
  BgUrgQQACg==  
  -----END EC PARAMETERS-----  
  -----BEGIN EC PRIVATE KEY-----  
  MHQCAQEEIALxlDOugVRY/0nG84pmdM2e4p2T4N8lxw2IEAzKLdHeoAcGBSuBBAAK  
  oUQDQgAE5qsUg+aH9ecjRmqRol3fYncUf7f0HMluLpRi0LtxwKV9hVcG07uvASIt  
  glBMk9XnzxDlGpCKfH7WOUMCeVtXLQ==  
  -----END EC PRIVATE KEY-----  

3. 生成公钥参数

# openssl ec -in ec_private_key.pem -pubout -out ec_public_key.pem  

4. 显示秘钥信息

# openssl ec -in ec_private_key.pem -text  
read EC key  
Private-Key: (256 bit)  
priv:  
   02:f1:94:33:ae:81:54:58:ff:49:c6:f3:8a:66:74:  
   cd:9e:e2:9d:93:e0:df:25:c7:0d:88:10:0c:ca:2d:  
   d1:de  
pub:  
   04:e6:ab:14:83:e6:87:f5:e7:23:46:6a:91:a2:5d:  
   df:62:77:14:7f:b7:f4:1c:c9:6e:2e:94:62:d0:bb:  
   71:c0:a5:7d:85:57:06:d3:bb:af:01:22:2d:82:50:  
   4c:93:d5:e7:cf:10:e5:1a:90:8a:7c:7e:d6:39:43:  
   02:79:5b:57:2d  
ASN1 OID: secp256k1  
writing EC key  
-----BEGIN EC PRIVATE KEY-----  
MHQCAQEEIALxlDOugVRY/0nG84pmdM2e4p2T4N8lxw2IEAzKLdHeoAcGBSuBBAAK  
oUQDQgAE5qsUg+aH9ecjRmqRol3fYncUf7f0HMluLpRi0LtxwKV9hVcG07uvASIt  
glBMk9XnzxDlGpCKfH7WOUMCeVtXLQ==  
-----END EC PRIVATE KEY-----  
# openssl ec -in ec_public_key.pem -pubin -text  
read EC key  
Private-Key: (256 bit)  
pub:  
   04:e6:ab:14:83:e6:87:f5:e7:23:46:6a:91:a2:5d:  
   df:62:77:14:7f:b7:f4:1c:c9:6e:2e:94:62:d0:bb:  
   71:c0:a5:7d:85:57:06:d3:bb:af:01:22:2d:82:50:  
   4c:93:d5:e7:cf:10:e5:1a:90:8a:7c:7e:d6:39:43:  
   02:79:5b:57:2d  
ASN1 OID: secp256k1  
writing EC key  
-----BEGIN PUBLIC KEY-----  
MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAE5qsUg+aH9ecjRmqRol3fYncUf7f0HMlu  
LpRi0LtxwKV9hVcG07uvASItglBMk9XnzxDlGpCKfH7WOUMCeVtXLQ==  
-----END PUBLIC KEY-----  

  1. OpenSSL库对椭圆曲线加密算法编程

#include <openssl/ec.h>      // for EC_GROUP_new_by_curve_name, EC_GROUP_free, EC_KEY_new, EC_KEY_set_group, EC_KEY_generate_key, EC_KEY_free
#include <openssl/ecdsa.h>   // for ECDSA_do_sign, ECDSA_do_verify
#include <openssl/obj_mac.h> // for NID_secp256k1
#include <openssl/ssl.h>
#include <openssl/bio.h>
#include <stdio.h>
#include <string.h>

EC_KEY * generate_eckey()
{
    EC_KEY *eckey=EC_KEY_new();
    EC_GROUP *ecgroup= EC_GROUP_new_by_curve_name(NID_secp256k1);
    EC_KEY_set_group(eckey, ecgroup);
    EC_KEY_generate_key(eckey);

    return eckey;
}


void write_private_key_to_pem(const char *priv_key_file_name, EC_KEY *eckey)
{
	FILE *fp = fopen(priv_key_file_name, "w");
	PEM_write_ECPrivateKey(fp, eckey, NULL, NULL, 0, NULL, NULL);
	fclose(fp);

	return;
}


EC_KEY *read_private_key_from_pem(const char *priv_key_file_name)
{
	FILE *fp = fopen(priv_key_file_name, "r");
	EC_KEY *eckey = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL);
	fclose(fp);

	return eckey;
}

void write_public_key_to_pem(const char *pubkey_file_name, EC_KEY *eckey)
{
	BIO *out = BIO_new_file(pubkey_file_name, "w");
	if(out == NULL)
	{
		printf("write public key to pem file failed! (%s:%d)\n", __FILE__,__LINE__);
	}
	PEM_write_bio_EC_PUBKEY(out, eckey);
	BIO_free(out);

	return ;
}

EC_KEY *read_public_key_from_pem(const char *pubkey_file_name)
{
	//BIO *in = BIO_new(BIO_s_file());
	//BIO_read_filename(in, pubkey_file_name);

	BIO *in = BIO_new_file(pubkey_file_name, "r");
	EC_KEY *eckey = EC_KEY_new();
	eckey = PEM_read_bio_EC_PUBKEY(in, &eckey, NULL, NULL);
	//EC_KEY *eckey = d2i_EC_PUBKEY_bio(in, NULL);

	//FILE *fp = fopen(pubkey_file_name, "r");
	//eckey = PEM_read_EC_PUBKEY(fp, &eckey, NULL, NULL);

	if (eckey == NULL)
	{
		printf("read public key pem failed! (%s:%d)\n", __FILE__, __LINE__);
	}
	BIO_free(in);

	return eckey;
}

int main()
{
	//read private or public key from pem file
	EC_KEY *privkey = read_private_key_from_pem("ec_private_key.pem");
	EC_KEY *pubkey = read_public_key_from_pem("ec_public_key.pem");

	//print key to stdout
	BIO *bio_stdout = BIO_new_fp(stdout, BIO_NOCLOSE);
	EC_KEY_print(bio_stdout, privkey, 0);
	printf("================================================================\n");
	EC_KEY_print(bio_stdout, pubkey, 0);

	printf("================================================================\n");
	//print g point
	EC_GROUP *ec_group = EC_KEY_get0_group(pubkey);
	EC_POINT *ec_point = EC_GROUP_get0_generator(ec_group);
	char *G = EC_POINT_point2hex(ec_group, ec_point,POINT_CONVERSION_UNCOMPRESSED, NULL);
	printf("G = %s\n", G);

	//print private key bignum
	BIGNUM *ec_privkey = EC_KEY_get0_private_key(privkey);
	//BN_print_fp(stdout, ec_privkey);
	char *k = BN_bn2hex(ec_privkey);
	printf("k = %s\n", k);

	//print public key point
	EC_POINT *ec_pubkey = EC_KEY_get0_public_key(privkey);
	char *K = EC_POINT_point2hex(ec_group, ec_pubkey,POINT_CONVERSION_UNCOMPRESSED, NULL);
	printf("K = %s\n", K);

	//print K = kG
	BN_CTX *ctx = BN_CTX_new();
	EC_POINT *r = EC_POINT_new(ec_group);
	EC_POINT_mul(ec_group, r, NULL, ec_point, ec_privkey, ctx);
	char *PK = EC_POINT_point2hex(ec_group, r,POINT_CONVERSION_UNCOMPRESSED, NULL);
	printf("kG = %s\n", PK);

	//print cofactor
	BIGNUM *cofactor = EC_GROUP_get0_cofactor(ec_group);
	char *p = BN_bn2hex(cofactor);
	printf("p = %s\n", p);

	//conversion string to bignum
	printf("================================================================\n");
	char *msg = "hello world";
	BIGNUM *m = BN_new();
	BN_bin2bn((unsigned char *)msg, strlen(msg),m);
	char *str_m = BN_bn2hex(m);
	printf("(string)m = %s, (hex)m = %s\n", msg, str_m);

	//extract the message digest
	printf("================================================================\n");
	int md_len;
	unsigned char md_value[EVP_MAX_MD_SIZE];
	EVP_MD_CTX *md = EVP_MD_CTX_new();
	EVP_DigestInit_ex(md, EVP_sha256(), NULL);
	EVP_DigestUpdate(md, msg, sizeof(msg));
	EVP_DigestFinal_ex(md, md_value, &md_len);
	BIGNUM *hash = BN_new();
	BN_bin2bn(md_value, md_len, hash);
	char *str_hash = BN_bn2hex(hash);
	printf("hash = %s\n ", str_hash);

	printf("================================================================\n");
	return 0;
}

编译:

# gcc main.c -g -o exam  -lcrypto

“OpenSSL WIKI”