Добавить необязательные атрибуты в ключ OpenSSL pkcs8 - PullRequest
1 голос
/ 02 ноября 2019

Согласно rfc5208, https://tools.ietf.org/html/rfc5208#page-3, ключи pkcs8 могут иметь дополнительные атрибуты.

Как я могу сгенерировать ключ RSA с этими дополнительными атрибутами? Я видел только параметр для openssl genpkey pkeyopt, в котором я могу указать такие вещи, как rsa_keygen_bits:2048, чтобы установить размер ключа, но если я хочу сделать что-то вроде добавления необязательного атрибута для имени, связанного с этим закрытым ключом, как бы ясделать это?

1 Ответ

0 голосов
/ 05 ноября 2019

Вы не можете сделать это с помощью командной строки, что может быть удачно, так как это не будет проблемой программирования и, следовательно, не слишком актуально для SO. Итак, вот минимальный запрограммированный пример:

/* SO58667890 19nov04 PKCS8 attribute */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <openssl/asn1.h>
#include <openssl/err.h>
#include <openssl/objects.h>
#include <openssl/pem.h>
#include <openssl/pkcs12.h>
#include <openssl/x509.h>

void err (const char * s, int n){ fprintf(stderr, "%s:%d\n", s,n); ERR_print_errors_fp (stderr); exit(1); }

int main (int argc, char** argv){
  if( argc < 4 ){ fprintf(stderr, "Usage: %s privkey.pem attrname attrvalue\n"); return 0; }
  int rv;

  BIO *bio = BIO_new_file (argv[1],"r");
  if( !bio ) err("BIO_new_file-r",0);
  EVP_PKEY *pkey = PEM_read_bio_PrivateKey (bio, NULL, NULL,NULL);
  if( !pkey ) err("PEM_read_bio_PrivateKey",0);
  PKCS8_PRIV_KEY_INFO *p8inf = EVP_PKEY2PKCS8 (pkey);
  if( !p8inf ) err("EVP_PKEY2PKCS8",0);

  int nid = OBJ_txt2nid (argv[2]);
  if( nid == NID_undef ) err("OBJ_txt2nid",nid); 

#if OPENSSL_VERSION_NUMBER >= 0x1010000fL 
  rv = PKCS8_pkey_add1_attr_by_NID (p8inf, nid, V_ASN1_IA5STRING, (unsigned char*)argv[3], strlen(argv[3]));
  if( !rv ) err("PKCS8_pkey_add1_attr_by_NID",rv);
#else
  if( !X509at_add1_attr_by_NID (&p8inf->attributes, nid, V_ASN1_IA5STRING, (unsigned char*)argv[3], strlen(argv[3])) )
    err("X509at_add1_attr_by_NID",0);
#endif

  bio = BIO_new_file (argv[1],"w");
  if( !bio ) err("BIO_new_file-w",0);
  rv = PEM_write_bio_PKCS8_PRIV_KEY_INFO (bio, p8inf);
  if( !rv ) err("PEM_write_bio_PKCS8info",rv);
  rv = BIO_free(bio);
  if( !rv ) err("BIO_free",rv);

  return 0;
}

Однако, как прокомментировал Мартен, эти атрибуты используются очень редко. Я видел по крайней мере один случай здесь , где Java вообще не реализовывала их. В мире PKI, включая S / MIME и SSL / TLS, у вас обычно есть сертификат X.509 (или PKIX) для публичного ключа, совпадающего с вашим приватным ключом, и этот сертификат содержит много полезной информации о личности владельца и разрешенном использовании. ключа - и эта информация находится в форме, которую программы в основном понимают и могут использовать (хотя время от времени возникают проблемы с одной стороной или системой, создающей новое расширение сертификата, которое не понимается другой стороной или системой). Например, когда вы смотрите в Windows certmgr или MacOS цепочку для ключей, вы не видите приватный ключ как таковой;Вы видите сертификат с прикрепленным к нему приватным ключом .

...