如何通过CA的公钥验证数字证书

时间:2015-10-28 08:21:56

标签: php openssl pki digital-certificate

我正在研究PKI(公钥基础设施)中的数字证书。几乎所有关于此的手册/页面都给出了类似的步骤。

  1. 获取主题标识+主题公钥,(与主题私钥的AND / OR加密消息哈希)并构建证书。
  2. 使用CA的私钥签名证书
  3. 在目的地,使用CA的公钥验证证书
  4. 现在我能够在php(使用openssl lib)中找到第一步和第二步的方法,它可以通过openssl API生成证书并签名(可选择生成签名哈希并签名)。

    但问题是第三步,它们没有指导或函数调用,显示如何使用CA的公钥验证证书。

    如果我遗失了什么?

    示例代码我检查如下

    $data = 'my data';
    
    //create new private and public key
    $req_key = openssl_pkey_new(array(
        "private_key_bits" => 2048,
        "private_key_type" => OPENSSL_KEYTYPE_RSA,
    ));
    
    $dn = array(
                    "countryName"            => "IN",
                    "stateOrProvinceName"    => "Delhi",
                    "organizationName"       => "example.net",
                    "organizationalUnitName" => "Security",
                    "commonName"             => "example.net"
                    );
    $req_csr  = openssl_csr_new ($dn, $req_key);
    $req_cert = openssl_csr_sign($req_csr, null, $req_key, 365);
    openssl_x509_export ($req_cert, $out_cert);
    
    echo $out_cert;
    

    背景:我需要为某些应用程序实现基于PKI的数据共享/验证。它将涉及一些数据实体(数据实体将在公共和私钥上加密)在源端加密然后发送到目的地。然后目的地解密并获得清晰的数据。但整体必须涉及PKI,这意味着数字签名+数字证书的实施以及。

2 个答案:

答案 0 :(得分:0)

这个任务在PHP中并不是那么简单。实际上,PHP并不是实现CA内容的好工具。它支持基本的PKI操作,但仅此而已。我看到三个选项:

  1. X.509只是DER编码的ASN.1结构。例如,您可以使用guiDumpASN-ng进行检查。 PHP世界中也有一些ASN.1库。基本上,CA签名在证书内。如果您能够提取它,则可以自行验证数字签名。
  2. http://php.net/manual/en/function.openssl-verify.php#98282

    1. 尝试使用openssl-x509-checkpurpose这样能够检查certificate chain的功能。

    2. 尝试使用phpseclib - 查看验证X.509证书 - > validateSignature()。

    3. 我希望它会对你有所帮助。

答案 1 :(得分:0)

不要搞乱自己实施证书验证,而是寻找CPV(证书路径验证)算法的实现,该算法包括在认证链中需要执行的所有验证,其中证书签名验证只是其中之一。

现在,我一直在寻找一个PHP API来执行CPV,但我没有找到,所以我使用PHP执行以下外部OpenSSL命令:

func badgeSizeForString(string:String) -> NSSize {
    var size = string.size(withAttributes: [NSFontAttributeName: NSFont.systemFont(ofSize: 13.0)])

    // Paddings
    size.height += 2.0
    size.width += 12.0

    return size
}

func drawBadgeImageWithText(text:NSString, atPoint point: NSPoint) -> Void {
    let badgeSize = badgeSizeForString(string: text as String)
    var badgeRect = NSMakeRect(point.x - badgeSize.width,
                               point.y - badgeSize.height,
                               badgeSize.width,
                               badgeSize.height)

    NSGraphicsContext.saveGraphicsState()

    // Set a shadow
    let shadow = NSShadow()
    shadow.shadowColor = NSColor.black.withAlphaComponent(0.4)
    shadow.shadowBlurRadius = 1;
    shadow.shadowOffset = NSMakeSize(0, -1);
    shadow.set()

    // Draw white border
    var path = NSBezierPath(roundedRect: badgeRect,
                            xRadius:badgeSize.height / 2.0,
                            yRadius:badgeSize.height / 2.0)
    NSColor.white.setFill()
    path.fill()

    NSGraphicsContext.restoreGraphicsState()

    // Fill the background with red gradient
    badgeRect = NSInsetRect(badgeRect, -1.5, -1.5)
    path = NSBezierPath(roundedRect: badgeRect,
                        xRadius:badgeSize.height / 2.0,
                        yRadius:badgeSize.height / 2.0)
    NSColor(calibratedRed:192.0 / 255.0,
            green:0.0,
            blue:0.0,
            alpha:1.0).setFill()
    path.fill()

    let gradient = NSGradient(starting: NSColor(calibratedRed:241.0 / 255.0,
                                                green:113.0 / 255.0,
                                                blue:115.0 / 255.0,
                                                alpha:1.0),
                              ending: NSColor(calibratedRed:192.0 / 255.0,
                                              green:0.0,
                                              blue:0.0,
                                              alpha:1.0))
    gradient?.draw(in: path, angle:-90.0)

    // Draw the text
    let paragraphStyle = NSMutableParagraphStyle()
    paragraphStyle.alignment = .center

    let textAttributes = [ NSForegroundColorAttributeName: NSColor.white, NSParagraphStyleAttributeName: paragraphStyle ]
    text.draw(in: badgeRect, withAttributes: textAttributes)
}

所有exec("openssl verify -CAfile trusted_root_cas.pem -untrusted intermediate_cas.pem endentity_cert.pem", $output, $return_var); if ($return_var == 0) { echo "Certification path validation completed successfully"; } else { echo "Certification path validation completed with errors"; } trusted_root_cas.pemintermediate_cas.pem都可以是为执行上一个命令而创建的临时文件。

现在,如果您想知道endentity_cert.pem的作用,请执行openssl verify

  

verify命令验证证书链。