我正在尝试使用 php 在服务器上完全签署一个 android .apk 文件。
为此,我需要在 .apk 文件(本质上是一个 ZIP 文件)内生成 META-INF 目录中包含的文件。在 php 中创建 .MF 和 .SF 文件相当简单。但是,我正在努力处理 .RSA 文件。
不幸的是,我对密码学一无所知,甚至不了解基本术语。我只知道一些 PHP 基础知识,但我经验不足,也没有必要的库/函数的概述。因此,即使经过数小时的研究,我仍然无法创造出任何有用的东西。
据我了解, .RSA 文件应包含:
- .SF 文件的数字签名
- 带有签名者公钥的证书
此文件应为 PKCS7 格式。
我试图为此使用 phpseclib。我能够从互联网上的示例创建一个私钥/公钥/证书,但我绝对无法将它们全部放在一起形成 .RSA 文件。
Stackoverflow 是一个很好的信息来源,我可能在这里找到了我问题的大部分答案。但是,现在我被困住了。
你们能给我一些php示例代码(理想情况下)吗?甚至是一些伪代码/算法……这甚至可以用 phpseclib/php 完成吗?是否有必要进行一些“位移”?如果可以的话,请不要指点我jarsigner的源码……我看了,对java不太了解,只会带来更多的问题。
更新:
当您不知道自己实际在做什么时,很难朝着正确的方向前进:D…</p>
这是我迄今为止尝试过的,但没有任何成功:
我用 ssh 生成了公钥/私钥对
ssh-keygen -t rsa1
我使用之前生成的密钥对来创建带有 phpsceclib 的自签名证书,如下所述:http: //phpseclib.sourceforge.net/new/x509/tutorial.html#selfsigning
我将证书($signcert)、私钥($privkey - 来自 ssh 生成的文件)和用于签名的数据($infilename –> .SF 文件)传递给 openssl 函数 openssl_pkcs7_sign():
openssl_pkcs7_sign ($infilename , $outfilename , $signcert , $privkey , array(), PKCS7_DETACHED|PKCS7_BINARY);
但是,生成的结果似乎是一种称为 PEM 格式(人类可读)的格式。除了它不是最终的 .RSA 文件应该是二进制 DER(甚至不知道那是什么……只是猜测它应该是 DER)这一事实之外,它还存在一些其他问题:
- 结果还包含 .SF 文件的内容(要自己签名的原始数据)
- 它包含一些不必要的标题信息作为常规文本字符串
- 行以“\n”结尾,而不是“\r\n”</li>
- 签名(不确定结果中的其他数据是什么,但可能是签名)是 base64 编码的
我至少在这里做点什么吗?还需要采取哪些其他步骤才能使其发挥作用?根据上述链接创建证书时应该设置哪些属性?如何将结果传输到二进制 DER 格式的 .RSA 文件,其中包含 .SF 签名和带有签名者公钥的证书?
更新 2:
我终于有时间继续我的小实验了。我浏览了我的代码并尝试更改不同的参数。最后我发现了问题。看来我只需要在 openssl_pkc7_sign() 中打开 PKCS7_NOATTR 标志。
这是代码
$configs = array('digest_alg' => 'sha1',
'x509_extensions' => 'v3_ca',
'req_extensions' => 'v3_req',
'private_key_bits' => 1024,
'private_key_type' => OPENSSL_KEYTYPE_RSA,
'encrypt_key' => true,
'encrypt_key_cipher' => OPENSSL_CIPHER_3DES);
// Generate private/public key pair and certificate
$privkey = openssl_pkey_new($configs);
$dn = array("commonName" => "name",
"emailAddress" => "me@example.com");
$csr = openssl_csr_new($dn, $privkey, $configs);
$sscert = openssl_csr_sign($csr, NULL, $privkey, 999, $configs);
// Sign the .SF file
openssl_pkcs7_sign ( $sfFile , $rsaFile , $sscert , $privkey, array(),
PKCS7_DETACHED|PKCS7_BINARY|PKCS7_NOATTR);
我只有时间在几个样本上检查它,但它现在似乎正在工作。这是一个非常简单的演示www.balabeng.com/?q=appsigner