Có thể xuất chứng chỉ và khóa cá nhân sang .pfx dọc theo bằng chuỗi chứng chỉ (root cert và/hoặc trung gian), sử dụng PHP openssl_pkcs12_export()
?chuỗi xuất khẩu với openssl_pkcs12_export trong PHP
CẬP NHẬT: Tôi đã lấy một cái nhìn tại nguồn cho phần mở rộng openssl php, và thấy rằng openssl_pkcs12_export()
hỗ trợ 2 args khác hơn so với những người trong tài liệu, friendly_name
và extracerts
. Đây là từ ext/openssl/openssl.c
, hãy kiểm tra dòng 1914-1920 (PHP-5.4.0):
1878 /* {{{ proto bool openssl_pkcs12_export(mixed x509, string &out, mixed priv_key, string pass[, array args])
1879 Creates and exports a PKCS12 to a var */
1880 PHP_FUNCTION(openssl_pkcs12_export)
1881 {
1882 X509 * cert = NULL;
1883 BIO * bio_out;
1884 PKCS12 * p12 = NULL;
1885 zval * zcert = NULL, *zout = NULL, *zpkey, *args = NULL;
1886 EVP_PKEY *priv_key = NULL;
1887 long certresource, keyresource;
1888 char * pass;
1889 int pass_len;
1890 char * friendly_name = NULL;
1891 zval ** item;
1892 STACK_OF(X509) *ca = NULL;
1893
1894 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zzzs|a", &zcert, &zout, &zpkey, &pass, &pass_len, &args) == FAILURE)
1895 return;
1896
1897 RETVAL_FALSE;
1898
1899 cert = php_openssl_x509_from_zval(&zcert, 0, &certresource TSRMLS_CC);
1900 if (cert == NULL) {
1901 php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get cert from parameter 1");
1902 return;
1903 }
1904 priv_key = php_openssl_evp_from_zval(&zpkey, 0, "", 1, &keyresource TSRMLS_CC);
1905 if (priv_key == NULL) {
1906 php_error_docref(NULL TSRMLS_CC, E_WARNING, "cannot get private key from parameter 3");
1907 goto cleanup;
1908 }
1909 if (cert && !X509_check_private_key(cert, priv_key)) {
1910 php_error_docref(NULL TSRMLS_CC, E_WARNING, "private key does not correspond to cert");
1911 goto cleanup;
1912 }
1913
1914 /* parse extra config from args array, promote this to an extra function */
1915 if (args && zend_hash_find(Z_ARRVAL_P(args), "friendly_name", sizeof("friendly_name"), (void**)&item) == SUCCESS)
1916 friendly_name = Z_STRVAL_PP(item);
1917
1918 if (args && zend_hash_find(Z_ARRVAL_P(args), "extracerts", sizeof("extracerts"), (void**)&item) == SUCCESS)
1919 ca = php_array_to_X509_sk(item TSRMLS_CC);
1920 /* end parse extra config */
1921
1922 p12 = PKCS12_create(pass, friendly_name, priv_key, cert, ca, 0, 0, 0, 0, 0);
1923
1924 bio_out = BIO_new(BIO_s_mem());
1925 if (i2d_PKCS12_bio(bio_out, p12)) {
1926 BUF_MEM *bio_buf;
1927
1928 zval_dtor(zout);
1929 BIO_get_mem_ptr(bio_out, &bio_buf);
1930 ZVAL_STRINGL(zout, bio_buf->data, bio_buf->length, 1);
1931
1932 RETVAL_TRUE;
1933 }
1934
1935 BIO_free(bio_out);
1936 PKCS12_free(p12);
1937 php_sk_X509_free(ca);
1938
1939 cleanup:
1940
1941 if (keyresource == -1 && priv_key) {
1942 EVP_PKEY_free(priv_key);
1943 }
1944 if (certresource == -1 && cert) {
1945 X509_free(cert);
1946 }
1947 }
1948 /* }}} */
Tuy nhiên, tôi không hoàn toàn chắc chắn làm thế nào để vượt qua các chứng chỉ bổ sung đối số ... bất kỳ manh mối?
Hãy cho tôi biết nếu nó dễ đọc hơn nếu không có số dòng
Rất tốt, cảm ơn. Loại biến nào sẽ là $ CAcert trong ngữ cảnh này? Chỉ cần một chuỗi hoặc đầu ra từ một PEM đọc với openssl_x509_read() hoặc cái gì? Vui lòng cung cấp ví dụ nếu bạn có thể –
@ MathiasR.Jessen Nội bộ '$ CAcert' được chuyển đến http://lxr.php.net/opengrok/xref/PHP_5_4/ext/openssl/openssl.c#1741 và điều này sẽ phát hiện nếu nó một mảng các certs hoặc một cert duy nhất, mỗi phần tử phải là một 'x509 Resource'. Tôi đã không thực hiện điều này trước nhưng tôi rất nghi ngờ giả định của bạn 'openssl_x509_read' là chính xác khi nó trả về loại tài nguyên đó. – Incognito
Tuyệt, tôi sẽ cố gắng triển khai bằng cách sử dụng phương pháp này và quay lại, cảm ơn –