是否可以在CSR上为subjectAltName设置x509 v3扩展属性?
我能够成功生成CSR,然后将其传递给CA进行签名。
CA可以调用X509-> setDomain(" bob.com"," * .bob.com"," asdf.org&#34)等功能);并且它们出现在最终证书中没有问题(注意:我正在执行签名,重新加载,设置扩展,为phpseclib重新签名解决方法)。
CSR流程调用相同的函数$ X509-> setExtension(" id-ce-subjectAltName",array(" names"," here") )或$ X509-> setDomain(" domain1"," domain2");似乎没有在CSR本身设置一些X509扩展属性(openssl可以),我只能在第二次签名之前重新导入后由CA添加SAN。
谢谢!
编辑:我创建了一个示例CSR(签名,重新加载,x509v3扩展,重新签名解决方法),似乎可以设置SOME扩展属性(CA:false,密钥用法等),但不是subjectAltName信息:
-----BEGIN CERTIFICATE REQUEST-----
MIIC1TCCAb8CAQAwVDELMAkGA1UEBgwCU1MxEDAOBgNVBAgMB09ic2N1cmUxDzAN
BgNVBAcMBlNlY3VyZTEQMA4GA1UECgwHYm9iY29ycDEQMA4GA1UEAwwHYm9iLmNv
bTCCASAwCwYJKoZIhvcNAQEBA4IBDwAwggEKAoIBAQCunNrjxEOILsESZ1osUkT3
zSeAHlzNiCBQnc/Xf+oW7Ir7wKfbHkV10cM583mw3Zy8rlCT/lUq0H+f3Uoc5/FA
dsYWhatlJRlTjv+yjSsxyB9i/hZ/KliP3Ix2O+Pq1wZIWfvk40hmCHHSB6YDtqt0
vXqUTIhH3SfyLtK9nd/6WG8bgIq9jgL6xvF3h44ynEwkuOnHt4a9WrflGX4KKcwo
OM98M/TAntDgSXBEYoLxenIbl3ypa7gtghVHHls3QOSay5QM87K3PJ3kSWVlZ3tN
tZGfbFdLiS+3MH8G3ujSX8XYeBnUj5jXi4SzpzQ9o5pyArL8DD8kC/Q9P/el1aZb
AgMBAAGgQDA+BgkqhkiG9w0BCQ4xMTAvMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/
BAwwCgYIKwYBBQUHAwEwBwYDVR0RBAAwCwYJKoZIhvcNAQELA4IBAQAUIhgLf6LH
WwhncU+yrNy6yHPHjFbipehUaS/Wa6FBbANpLyEdslqNwFD2FyXofSQVCB0L6VnH
NNXHcfZqWOT8+Xd0yNmfr/w+vg+s1yY4S0VAG6mxGsqwdIJqgXm2jaw0rMpzRs/k
wfOpJ+gyRTrQz9VJrn4xC4Uv6zTGNj56qZehDievW74SGISbGzj7AGmCxpp5/qZD
LN4Ls3wZ7I4TfuYZDh7qWuFwEAEEv40JPF2qO3VitvyAYrKg3bnUlFzQrOsfs4Ot
xzihLwkFEobih1bOEhzTnSv+lMckfw0DQ5Eb8mtFTC+/KOqEMMU5Hq1fm3B9Bkgs
FmqQZk4QlerY
-----END CERTIFICATE REQUEST-----
答案 0 :(得分:1)
我想通了,phpseclib中的SignCSR函数没有重新启动setDomain函数,或者$ this->域数组中的任何内容,但是可以手动编码并强制设置主题alt名称:
$OPTIONS["altnames"] = array(
"bob.com",
"10.123.123.123",
"*.bob.com",
"asdf.fdsa",
);
$ALTNAMES = $this->altnames($OPTIONS["altnames"]);
if ( count($ALTNAMES) )
{
$CSR->setExtension("id-ce-subjectAltName" , $ALTNAMES );
}
protected function altnames($ALTNAMES)
{
//Sort names and IPs into two different arrays
$DOMAINS = array(); $IPS = array();
foreach ($ALTNAMES as $ALTNAME)
{
if ( filter_var($ALTNAME, FILTER_VALIDATE_IP) )
{
array_push($IPS,$ALTNAME);
}else{
array_push($DOMAINS,$ALTNAME);
}
}
// Create our altname array for the subjectAltName parser
$RETURN = array();
foreach ($DOMAINS as $DOMAIN) { array_push($RETURN, array("dNSName" => $DOMAIN ) ); }
foreach ($IPS as $IP) { array_push($RETURN, array("iPAddress" => $IP ) ); }
return $RETURN;
}
现在,我发现的一个警告(这是phpseclib要考虑的一个功能问题)是缺乏IPv6支持。如果您在altnames数组(2620:153 :: 1234)中提供有效的IPv6地址,它将转换为IP地址:0.0.0.0,因为使用了X509代码中嵌入的IP2LONG和LONG2IP。
虽然不是我的用例的一个showstopper,但这是一个小麻烦,我已经尝试使用自定义IP2BIN和BIN2IP功能替换库中IP的编码和解码逻辑,但没有取得很大成功。
使用上面的代码生成的CSR示例:
-----BEGIN CERTIFICATE REQUEST-----
MIIC/DCCAeYCAQAwVDELMAkGA1UEBgwCU1MxEDAOBgNVBAgMB09ic2N1cmUxDzAN
BgNVBAcMBlNlY3VyZTEQMA4GA1UECgwHYm9iY29ycDEQMA4GA1UEAwwHYm9iLmNv
bTCCASAwCwYJKoZIhvcNAQEBA4IBDwAwggEKAoIBAQDOGLdjEr2IyW27e08hmRN+
Bcu4uOWAWEvxvY3+5pHdBQQEXhww5YQuEvpmgbKtav0j7aqFPDYNSXTv+aQNe9fq
cP3nZmKAWU+qbQMjWxwV9mEJOlWI214v7C8lLbMvBlny141J7KTvv1TGGLCBH/V2
EnQSdJzGDwXmJ2k0iChlQ7zl1TlonamYX9gefzp3N/DDp6kNhuPSX9zRorYIp5CC
WEIRmDdegwxHACrNu0K4xwuPjTRJf0oUkRsfBuDxqvBalQ0bzd/23fiQ51MEVla3
fUWL/+b2SKOlvgfu0XbfZ+Qx21DeyRQpqIWnv0gR4AM8qltxUgRjZloUfK5IQ8rp
AgMBAAGgZzBlBgkqhkiG9w0BCQ4xWDBWMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/
BAwwCgYIKwYBBQUHAwEwLgYDVR0RBCcwJYIHYm9iLmNvbYIJKi5ib2IuY29tgglh
c2RmLmZkc2GHBAp7e3swCwYJKoZIhvcNAQELA4IBAQAf1Vlt09ZBhVpxlmi+n93u
Gm8fNrd5afeIzWj0h4dFGJSOg5T8SkfL5txk2C9tQEdayQWB1kllx5rIqXAPe6gz
kbcjJn8l2IB3khIoKYmylmtV8Yo0Fl/Xba1oLCAsixbK+UxiSLgXqMryz9DBy40s
5oYXpy5JOnqL7BRC7b+Lk/chw7CcncPZI4rei6HM8WATymTySdrPoQegvBj0VIar
qHBZrMV9lsjTREJ9hvA/FycA/PNlP9y8N+eTF9SBrnTi8ix+v+Iirc43xeD2EVLG
6uqXecClji6OEOKcdDsH0D0HD1PMFmKB0FWvq71dt7eVIHkTPwTLFG2XAjfn6Fb8
-----END CERTIFICATE REQUEST-----
解码为:
Certificate Request:
Data:
Version: 0 (0x0)
Subject: C=SS, ST=Obscure, L=Secure, O=bobcorp, CN=bob.com
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:ce:18:b7:63:12:bd:88:c9:6d:bb:7b:4f:21:99:
13:7e:05:cb:b8:b8:e5:80:58:4b:f1:bd:8d:fe:e6:
91:dd:05:04:04:5e:1c:30:e5:84:2e:12:fa:66:81:
b2:ad:6a:fd:23:ed:aa:85:3c:36:0d:49:74:ef:f9:
a4:0d:7b:d7:ea:70:fd:e7:66:62:80:59:4f:aa:6d:
03:23:5b:1c:15:f6:61:09:3a:55:88:db:5e:2f:ec:
2f:25:2d:b3:2f:06:59:f2:d7:8d:49:ec:a4:ef:bf:
54:c6:18:b0:81:1f:f5:76:12:74:12:74:9c:c6:0f:
05:e6:27:69:34:88:28:65:43:bc:e5:d5:39:68:9d:
a9:98:5f:d8:1e:7f:3a:77:37:f0:c3:a7:a9:0d:86:
e3:d2:5f:dc:d1:a2:b6:08:a7:90:82:58:42:11:98:
37:5e:83:0c:47:00:2a:cd:bb:42:b8:c7:0b:8f:8d:
34:49:7f:4a:14:91:1b:1f:06:e0:f1:aa:f0:5a:95:
0d:1b:cd:df:f6:dd:f8:90:e7:53:04:56:56:b7:7d:
45:8b:ff:e6:f6:48:a3:a5:be:07:ee:d1:76:df:67:
e4:31:db:50:de:c9:14:29:a8:85:a7:bf:48:11:e0:
03:3c:aa:5b:71:52:04:63:66:5a:14:7c:ae:48:43:
ca:e9
Exponent: 65537 (0x10001)
Attributes:
Requested Extensions:
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Extended Key Usage: critical
TLS Web Server Authentication
X509v3 Subject Alternative Name:
DNS:bob.com, DNS:*.bob.com, DNS:asdf.fdsa, IP Address:10.123.123.123
Signature Algorithm: sha256WithRSAEncryption
1f:d5:59:6d:d3:d6:41:85:5a:71:96:68:be:9f:dd:ee:1a:6f:
1f:36:b7:79:69:f7:88:cd:68:f4:87:87:45:18:94:8e:83:94:
fc:4a:47:cb:e6:dc:64:d8:2f:6d:40:47:5a:c9:05:81:d6:49:
65:c7:9a:c8:a9:70:0f:7b:a8:33:91:b7:23:26:7f:25:d8:80:
77:92:12:28:29:89:b2:96:6b:55:f1:8a:34:16:5f:d7:6d:ad:
68:2c:20:2c:8b:16:ca:f9:4c:62:48:b8:17:a8:ca:f2:cf:d0:
c1:cb:8d:2c:e6:86:17:a7:2e:49:3a:7a:8b:ec:14:42:ed:bf:
8b:93:f7:21:c3:b0:9c:9d:c3:d9:23:8a:de:8b:a1:cc:f1:60:
13:ca:64:f2:49:da:cf:a1:07:a0:bc:18:f4:54:86:ab:a8:70:
59:ac:c5:7d:96:c8:d3:44:42:7d:86:f0:3f:17:27:00:fc:f3:
65:3f:dc:bc:37:e7:93:17:d4:81:ae:74:e2:f2:2c:7e:bf:e2:
22:ad:ce:37:c5:e0:f6:11:52:c6:ea:ea:97:79:c0:a5:8e:2e:
8e:10:e2:9c:74:3b:07:d0:3d:07:0f:53:cc:16:62:81:d0:55:
af:ab:bd:5d:b7:b7:95:20:79:13:3f:04:cb:14:6d:97:02:37:
e7:e8:56:fc
答案 1 :(得分:1)
好吧,我想我找到了一个"功能"在phpseclib的X509签名功能中:
function sign($issuer, $subject, $signatureAlgorithm = 'sha1WithRSAEncryption')
如果您对CSR签名,则sign函数中的代码声称要复制X509 v3扩展属性,但是当它执行此行时:
$csrexts = $subject->getAttribute('pkcs-9-at-extensionRequest', 0);
结果总是空白(空数组),$ THIS(新)证书中的属性被覆盖在前30行代码中的某处。
我将csrexts行移到了Sign函数的顶部,现在正在将属性正确复制到CSR中具有X509扩展属性的生成证书中(必须手动计算并由我之前的答案设置)
我将使用sourceforge尝试发布错误请求以保存其他人的希望。
答案 2 :(得分:0)
好的,所以我使用PHPSecLib文档中的示例并使用它好几个小时来完成这项工作。也许这是2月份之后添加的内容,但无论如何,这里是如何使用主题备用名称生成CSR:
$privKey = new Crypt_RSA();
extract($privKey->createKey());
$privKey->loadKey($privatekey);
$x509 = new File_X509();
$x509->setPrivateKey($privKey);
$x509->setDNProp('id-at-organizationName', 'Company');
$x509->setDNProp('id-at-organizationalUnitName', 'CompanyDepartment');
$x509->setDNProp('id-at-commonName', 'myurl.com');
$x509->setDNProp('id-at-localityName', $this->application);
$x509->loadCSR($x509->saveCSR($x509->signCSR()));
// Set extension request.
$x509->setExtension("id-ce-subjectAltName", [
['dNSName' => 'myalternativename.com', 'iPAddress' => 127.0.0.1]
]);
echo $x509->saveCSR($x509->signCSR());
这应该用myalternativename.com作为SAN打印出CSR。
答案 3 :(得分:0)
该错误在2020年仍然存在。
此错误的原因是需要有效的$ x509-> currentCert数组。 setExtension()函数对空的currentCert数组无效。
currentCert数组结构等于signCSR()函数的结果。因此,您可以将其初始化如下:#@splits = map {exists $oneshot_replacement{$_} ? $oneshot_replacement{$_} : $_} @splits ;
@splits = map {exists $oneshot_replacement{$_} ? $oneshot_replacement{$_} : exists $pattern2replacement{$_} ? $pattern2replacement{$_} : $_} @splits ;
现在,您可以调用setExtension()函数。
以下是如何使用SAN属性生成CSR的完整示例:
$x509->currentCert = $x509->signCSR();