我使用以下命令创建了一个RSA私钥:
if ( isset( $session ) ) {
// graph api request for user data
$request = new FacebookRequest( $session, 'GET', '/me' );
$response = $request->execute();
// get response
$graphObject = $response->getGraphObject();
$fbid = $graphObject->getProperty('id'); // To Get Facebook ID
$fbfullname = $graphObject->getProperty('name'); // To Get Facebook full name
$femail = $graphObject->getProperty('email'); // To Get Facebook email ID
/* ---- Session Variables -----*/
$_SESSION['FBID'] = $fbid;
$_SESSION['FULLNAME'] = $fbfullname;
$_SESSION['email'] = $femail;
$args = array('scope' => 'email');
$_SESSION["args"] = $args;
/* ---- header location after session ----*/
header("Location: ../");
} else {
$loginUrl = $helper->getLoginUrl();
header("Location: ".$loginUrl);
}
?>
我必须为这个项目使用DER编码密钥(PKCS#1),所以我从这个PEM编码的私钥文件中生成了两个DER文件 - 一个带有私钥,另一个带有公钥。
openssl genrsa -out keypair.pem 2048
在我的代码中,我将这两个文件的内容加载到char *变量中。
以下任何一项都无法按预期工作:
openssl rsa -inform PEM -in keypair.pem -outform DER -pubout -out public.der
openssl rsa -inform PEM -in keypair.pem -outform DER -out private.der
我知道因为所有人都返回d2i_RSA_PUBKEY(NULL, &public_key_bytes, public_key_length);
d2i_RSAPublicKey(NULL, &public_key_bytes, public_key_length);
d2i_RSAPrivateKey(NULL, &private_key_bytes, private_key_length);
。我也尝试了以下内容:
null
全部返回RSA * rsa = RSA_new();
d2i_RSA_PUBKEY(&rsa, &public_key_bytes, public_key_length);
RSA * rsa = RSA_new();
d2i_RSAPublicKey(&rsa, &public_key_bytes, public_key_length);
RSA * rsa = RSA_new();
d2i_RSAPrivateKey(&rsa, &private_key_bytes, private_key_length);
。
我的完整测试代码如下:
null
我做错了什么?
答案 0 :(得分:3)
TLDR :d2i_RSA_PUBKEY
和d2i_RSAPrivateKey
应该有效,并且在Unix上为我做。
你说你想要'DER编码密钥(PKCS#1)'。
对于publickeys,OpenSSL通常使用X.509中定义的格式为SubjectPublicKeyInfo
,其中包含AlgorithmIdentifier
plus (已编辑)BIT STRING
,其中包含一个publickey值根据算法而变化的结构。对于RSA,algid包含标识RSA且没有参数的OID;依赖于算法的结构是PKCS#1。
相比之下,OpenSSL支持两种类型的私钥格式:每种算法都有一种“遗留”格式(DH除外),对于RSA,它是PKCS#1;和PKCS#8定义的通用格式(如SPKI)由AlgorithmIdentifier
加上依赖于算法的私钥值组成,这次是OCTET STRING
。 PKCS#8还有一个加密密钥的选项,SPKI没有或不需要。
OpenSSL的旧部分,包括genrsa
和rsa
命令行实用程序,使用旧的私钥格式,但是OpenSSL命名为PUBKEY的SPKI公钥格式。因此,您的rsa
命令创建了一个可由d2i_RSA_PUBKEY
读取的publickey文件,但不是d2i_RSAPublicKey
(只是PKCS#1部分)和d2i_RSAPrivateKey
可读的私钥文件。
如果您确实需要'裸'PKCS#1格式的publickey,rsa
实用程序有选项-RSAPublicKey_in
和-RSAPublicKey_out
来读取和写入此格式自1.0.0以来,尽管已记录仅在最近,仍未在帮助信息中。该文件可由d2i_RSAPublicKey
读取,但不能由d2i_RSA_PUBKEY
读取。
一种可能性:您没有提及操作系统。 DER文件是二进制的,而在C中正确处理Windows上的二进制文件,您必须使用fopen
修饰符b
,这里您需要"rb"
来读取二进制文件。如果我在Unix上运行你的代码它可以工作,但要在Windows上获得正确的结果我必须添加b
。
也是一个小问题:你谈论'加载内容......在char *变量中'。实际上,您将文件内容加载到内存中并使用char *
变量指向它们。严格来说,OpenSSL d2i
例程需要const unsigned char *
变量的地址 - 并且您的编译器应该至少警告您这种不匹配,如果您在符合标准的模式下运行它。但是C需要指向所有char
种类(signed
unsigned
和'plain')的指针,无论有没有限定条件,都具有相同的表示和对齐要求,即使它们不兼容如标准中所定义,因此将char **
传递到预期const unsigned char **
的位置确实有效。