生成本地CA根证书、p12流程 算法为RSA ECC算法移步
安装 OpenSSL:首先,确保你的系统上安装了 OpenSSL 工具。如果尚未安装,你可以通过 Homebrew 或从 OpenSSL 官方网站下载并安装。
创建根证书私钥:使用 OpenSSL 生成一个根证书的私钥文件。运行以下命令生成一个 2048 位的 RSA 私钥文件(root.key):
代码语言:javascript复制openssl genrsa -out root.key 2048
此命令将生成一个新的 RSA 私钥文件,用于根证书的签名和加密。
创建根证书:使用根证书私钥生成自签名的根证书。运行以下命令生成一个自签名的根证书文件(root.crt):
代码语言:javascript复制openssl req -x509 -new -key root.key -out root.crt
在终端中执行以下命令来生成私钥:
生成密码保护的私钥
代码语言:javascript复制openssl genpkey -algorithm RSA -out private.pem -aes256
或者生成无密码的私钥
代码语言:javascript复制penssl genpkey -algorithm RSA -out private.pem
创建证书请求文件:对于每个需要颁发证书的实体(例如服务器或客户端),你需要创建一个证书请求文件(CSR 文件)。运行以下命令生成一个证书请求文件
代码语言:javascript复制openssl req -new -key private.pem -out certificate.csr
签署证书:使用根证书的私钥签署证书请求,生成证书文件(certificate.crt)。运行以下命令生成签署的证书文件:(下级证书)
代码语言:javascript复制openssl x509 -req -in certificate.csr -CA root.crt -CAkey root.key -CAcreateserial -out certificate.crt
生成一个p12并设置密码
代码语言:javascript复制openssl pkcs12 -export -in certificate.crt -inkey private.pem -out certificate.p12
下面是OC使用p12做签名验签的简单示例
代码语言:javascript复制dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSData *p12Data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"certificate" ofType:@"p12"]];
NSDictionary *options = @{(__bridge id)kSecImportExportPassphrase: @"123456"};
CFArrayRef items = NULL;
OSStatus status = SecPKCS12Import((__bridge CFDataRef)p12Data, (__bridge CFDictionaryRef)options, &items);
if (status == errSecSuccess) {
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
SecIdentityRef identity = (SecIdentityRef)CFDictionaryGetValue(identityDict, kSecImportItemIdentity);
SecCertificateRef certificate = NULL;
SecIdentityCopyCertificate(identity, &certificate);
// 获取私钥
SecKeyRef privateKey = NULL;
SecIdentityCopyPrivateKey(identity, &privateKey);
// 获取公钥
SecPolicyRef policy = SecPolicyCreateBasicX509();
SecTrustRef trust;
SecTrustCreateWithCertificates(certificate, policy, &trust);
SecTrustResultType trustResult;
SecTrustEvaluate(trust, &trustResult);
SecKeyRef publicKey = SecTrustCopyPublicKey(trust);
NSString *testBase64 = @"Cy4JAEFCQ0QjMTIzNA4uBwAAAAEBAAABCi4gAJjruIAtnUTW0IkHex7/gCKJUb 927IrBoD40CP nZjdCS4uAHpoYW5nMyZKREpoSkRFd0pFcGpaVGc0V0ZsSE9HZHpkRWcyZWtGeVFXRnZMbVUNLggAAAABAAAAAQAMLkEABHTznz0bpFsvbiYz7gwwVwZEBU2hcRHEwKNDdyGCfKc1IktkBlDqUogUnfqJPUrnkKQCDaEU91zB2aQrBqoAvUo=";
NSData *signData = [[NSData alloc] initWithBase64EncodedString:testBase64 options:0];
SecKeyAlgorithm algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256;
CFErrorRef error = NULL;
NSData *signature = (NSData *)CFBridgingRelease(SecKeyCreateSignature(privateKey, algorithm, (__bridge CFDataRef)signData, &error));
if (error == NULL) {
// 加签成功,使用 signature 进行后续操作
SecKeyAlgorithm algorithm = kSecKeyAlgorithmRSASignatureMessagePKCS1v15SHA256;
BOOL result = SecKeyVerifySignature(publicKey, algorithm, (__bridge CFDataRef)signData, (__bridge CFDataRef)signature, NULL);
if (result) {
// 验签成功
NSLog(@"使用p12加签、验签成功");
} else {
// 验签失败
}
} else {
// 加签失败,处理错误
}
// 释放内存
if (identity) CFRelease(identity);
if (certificate) CFRelease(certificate);
if (privateKey) CFRelease(privateKey);
if (publicKey) CFRelease(publicKey);
}
});