生成本地CA根证书、p12流程

2023-10-14 19:16:44 浏览数 (3)

生成本地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);
        }
        
    });

0 人点赞