正在从RSA公钥中提取数据


Extracting data from RSA public key

我正在进行一个项目,该项目涉及读取用于签署Android APK的公钥数据。我能够成功地提取签名作为公钥。当我查看由此生成的二进制pubkey文件时,我会看到一些纯文本,如名称和城市。

如何使用PHP(甚至Java或C#)安全地提取嵌入公钥中的名称/城市信息希望这样做能让我准确地知道这些字段是什么(即不要盲目地抓取文本,而是知道哪个字符串是城市,哪个字符串是名字)

为了澄清:我没有私钥或证书文件。我目前对签名或加密任何东西都不感兴趣,我只想在不使用regex等笨拙方法的情况下提取公钥中的明文

更新:这是我的一个APK 中的一个样本(base64编码)公钥

MIICBzCCAXCgAwIBAgIES6KlazANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQGEwJVUzELMAkGA1UECBMCUkkxFTATBgNVBAcTDE5hcnJhZ2Fuc2V0dDEVMBMGA1UEAxMMQ29saW4gTydEZWxsMB4XDTEwMDMxODIyMTI1OVoXDTQ1MDMwOTIyMTI1OVowSDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlJJMRUwEwYDVQQHEwxOYXJyYWdhbnNldHQxFTATBgNVBAMTDENvbGluIE8nRGVsbDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAmPetcBW+ITURXY0LsI2ZfgM3R7K2kwicgpd0W+BYAXQBh76SXyN9MYvtfnUY3SNz37FW/lDQgAO3pbhEFqGwfADh2ctXlYmlE9DtcRQw0ojGVPIDlWBX+9IUxyL/89CPaN84R/1lvdosco4V0BqQYR300S9ZwmwFA2Vh9hSUZmsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBezKu4G11Z68NTPIBro8xsnbkdYxObzW7BsSr6t9MS5x6EQVs75R/nnKrsMcQ+9ImdT940jhQgZT3ZrYla5VhdbelxnLhBVbJfBdipV3Hv2bG7MnXzFqHYwQqYp+UrP8zWm1YHQf5I/P9VBjlkgwFyNKr0TxP4t/qS08oGX2wvZg==

您放入的字符串是一个基于64编码的x509证书,而不仅仅是一个公钥。

您需要解析"可分辨名称"字段以获得所需的信息。

下面是一个C#示例:

using System;
using System.Security.Cryptography.X509Certificates;
namespace Sample
{
class Program
{
    static void Main(string[] args)
    {
        string base64EncodedX509 =
            "MIICBzCCAXCgAwIBAgIES6KlazANBgkqhkiG9w0BAQUFADBIMQswCQYDVQQGEwJVUzELMAkGA1UECBMCUkkxFTATBgNVBAcTDE5hcnJhZ2Fuc2V0dDEVMBMGA1UEAxMMQ29saW4gTydEZWxsMB4XDTEwMDMxODIyMTI1OVoXDTQ1MDMwOTIyMTI1OVowSDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAlJJMRUwEwYDVQQHEwxOYXJyYWdhbnNldHQxFTATBgNVBAMTDENvbGluIE8nRGVsbDCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAmPetcBW+ITURXY0LsI2ZfgM3R7K2kwicgpd0W+BYAXQBh76SXyN9MYvtfnUY3SNz37FW/lDQgAO3pbhEFqGwfADh2ctXlYmlE9DtcRQw0ojGVPIDlWBX+9IUxyL/89CPaN84R/1lvdosco4V0BqQYR300S9ZwmwFA2Vh9hSUZmsCAwEAATANBgkqhkiG9w0BAQUFAAOBgQBezKu4G11Z68NTPIBro8xsnbkdYxObzW7BsSr6t9MS5x6EQVs75R/nnKrsMcQ+9ImdT940jhQgZT3ZrYla5VhdbelxnLhBVbJfBdipV3Hv2bG7MnXzFqHYwQqYp+UrP8zWm1YHQf5I/P9VBjlkgwFyNKr0TxP4t/qS08oGX2wvZg==";
        var rawBytes = Convert.FromBase64String(base64EncodedX509);
        X509Certificate cert = new X509Certificate(rawBytes);
        // Parse the distinguished name to get your desired fields
        Console.WriteLine(cert.Subject); // writes CN=Colin O'Dell, L=Narragansett, S=RI, C=US
        Console.WriteLine(cert.Issuer);  // writes CN=Colin O'Dell, L=Narragansett, S=RI, C=US
    }
}
}

"由此生成的二进制公钥文件"是X.509证书。

几乎任何平台都支持读取X.509证书,并从中创建一个结构,您可以从中可靠地提取"使用者名称",以及通常包括电子邮件地址或主机名的扩展信息。

例如,如果您安装了OpenSSL,请使用以下命令:

openssl x509 -text -noout -inform der -in <yourfilehere>

您可以使用其他选项提取特定字段。例如,添加-subject会产生

subject=/C=US/ST=RI/L=Narragasett/CN=Colin O'Dell

在php中,我不确定,但这个函数可能是你的朋友。如果您正在使用证书,那么有一整部分与ssl相关的函数可能会派上用场。