2

OpenSSLCAPIを使用してCSRを構築しています。コードは次のとおりです。

static void seedPRNG() {

const int openSSLseedsize = 128;

uint8_t *openSSLseed = NULL;
openSSLseed = malloc(openSSLseedsize * sizeof(uint8_t));
//printf("%d\n\n", openSSLseedsize);


// random number generator
SecRandomCopyBytes(kSecRandomDefault, openSSLseedsize, openSSLseed);

for (unsigned i = 0; i < openSSLseedsize; i++) {
    printf("%d", openSSLseed[i]);
}
printf("\n\n\n\n");
//seed openSSL random
RAND_seed(openSSLseed, 128);


}

// Parameter settings for this cert
//
#define RSA_KEY_SIZE (2048)
#define ENTRIES 3

// array of entries to assign to cert
struct entry {
char *key;
char *value;
};

struct entry entries[ENTRIES] =
{
{"emailAddress", "tomgrant@example.com"},
{"commonName", "internal.example.com"},
{"countryName", "GB"},
};

// Generate CSR

int generateCSR() {

int i;
RSA *rsakey;
X509_REQ *req;
X509_NAME *subj;
EVP_PKEY *pkey;
EVP_MD *digest;
FILE *fp;

// set up OpenSSl
OpenSSL_add_all_algorithms();
ERR_load_CRYPTO_strings();

// seed oppenssl's prng
seedPRNG();

// generate RSA key (no callback for progress - it's quick enough)
// RSA_F4 is 0x10001 (or 65537) for the exponent.
// RSA docs say exponent should be either 3, 5, 17, 257 or 65537 i.e. prime numbers. See here for further info:
// http://security.stackexchange.com/questions/2335/should-rsa-public-exponent-be-only-in-3-5-17-257-or-65537-due-to-security-c

rsakey = RSA_generate_key(RSA_KEY_SIZE, RSA_F4, NULL, NULL);



if (rsakey == NULL) {
    fatal("Could not create RSA key");
}

// Create EVP ("Envelope Encryption" apparently...) object to hold our rsakey
// generate private key
if (!(pkey = EVP_PKEY_new()))
   fatal("Could not create EVP object");
// assign the rsa key to EVP object
if (!(EVP_PKEY_set1_RSA(pkey, rsakey)))
    fatal("Could not assign RSA key to EVP object");

// create request object
if (!(req = X509_REQ_new()))
    fatal("Failed to create X509_REQ object");

// set the public key
X509_REQ_set_pubkey(req, pkey);


// create and fill in subject object
if (!(subj = X509_NAME_new()))
    fatal("Failed to create X509_NAME object");


for (i = 0; i < ENTRIES; i++)
{
    // create nid for every entry
    int nid; // ASN.1 numeric ID - ASN.1 = Abstract Syntax Notation One. Formal notation used to describe data transmitted by telecommunications protocols.
             // The NID is a unique internal ID assigned to every object. 

    X509_NAME_ENTRY *ent;

    if ((nid = OBJ_txt2nid(entries[i].key)) == NID_undef)
    {
        fprintf(stderr, "Error finding NID for %s\n", entries[i].key);
        fatal("Error on lookup");
    }
    if (!(ent = X509_NAME_ENTRY_create_by_NID(NULL, nid, MBSTRING_ASC, (unsigned char*)entries[i].value, -1)))
        fatal("Error creating Name entry from NID");

    if (X509_NAME_add_entry(subj, ent, -1, 0) != 1)
        fatal("Error adding entry to Name");

}


if (X509_REQ_set_subject_name(req, subj) != 1)
    fatal("Error adding subject to request");

// request is filled in and contains our generated public key
// now sign it
digest = (EVP_MD *)EVP_sha1();

if (!(X509_REQ_sign(req, pkey, digest)))
    fatal("Error signing request");

// write output files
//
NSString *docDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
// append file name
NSString *crtPath = [docDirectory stringByAppendingString:@"/example.crt"];
NSLog(@"crtPath = %@", crtPath);

if (!(fp = fopen([crtPath UTF8String], "w")))
    fatal("Error writing to request file");
if (PEM_write_X509_REQ(fp, req) != 1)
    fatal("Error writing request");
fclose(fp);

NSString *keyPath = [docDirectory stringByAppendingString:@"/example.key"];
NSLog(@"keyPath = %@", keyPath);
if (!(fp = fopen([keyPath UTF8String], "w")))
    fatal("Error writing to private key file");
if (PEM_write_PrivateKey(fp, pkey, NULL, NULL, 0, 0, NULL) != 1)
    fatal("Error while writing private key");
fclose(fp);

 X509_REQ_print_fp(stdout, req);


EVP_PKEY_free(pkey);
X509_REQ_free(req);



return 0;

}

これにより、CSRが作成され、秘密鍵も出力されます。オンラインのCSRチェッカーを使用してCSRを確認できますが、正しいと言って全体的にチェックマークが付いています。Windows2008R2CAを使用してbase64CSRを貼り付けています。ただし、リクエストを送信すると、Windowsボックスは次のエラーを返します。

リクエストIDは0です。処理メッセージは「リクエストASN1の不正なタグ値が満たされました。0x8009310b(ASN:267)の解析エラーです」です。

これは、オープンSSLに付属するmkreq.cサンプルコードを使用してCSRを生成する場合にも発生します。

誰かがこれに遭遇したことがありますか?私のオンライン調査では、CA(GoDaddyなど)から発行されたファンキーな証明書からこのエラーが発生する人しかいませんでした。

どんな助けでも大歓迎です!

4

1 に答える 1

2

(編集でOPによって回答されました。回答のない質問を参照してください。ただし、コメントで問題は解決されています(またはチャットで拡張されています)

OP は次のように書いています。

さて、私の同僚と私は最終的に解決策を見つけました。

ASN.1 表現 (openssl asn1parse を使用) を見ると、BAD CSR に次の表現があることに気付きました。

8:d=2  hl=2 l=   0 prim: INTEGER           :00

l = 0 に注意してください (これは長さを意味すると思います)。次に、良い CSR:

8:d=2  hl=2 l=   1 prim: INTEGER           :00

注意 l = 1

これは、CSR のバージョン番号を設定することで修正されます (RFP では、0 に設定する必要があると記載されています)。

だから - X509_REQ_set_version(req, 0); を使用して サーバー 2008R2 は問題を修正し、私の最愛のアイデンティティーを与えてくれました!

于 2015-01-26T19:47:19.797 に答える