我正在使用 OpenSSL C API 来构建 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,它会到处打勾,表示它是正确的。我正在使用 Windows 2008R2 CA 粘贴 base64 CSR。但是,当我提交请求时,Windows 框会返回以下错误:
您的请求 ID 为 0。处置消息是“错误解析请求 ASN1 错误标记值。0x8009310b (ASN: 267)”。
使用 open SSL 附带的 mkreq.c 示例代码生成 CSR 时也会发生这种情况。
有没有人遇到过这个?我的在线研究只发现人们从 CA(GoDaddy 等)颁发的时髦证书中得到这个错误。
非常感激任何的帮助!