【问题标题】:Extracting data from RSA public key从 RSA 公钥中提取数据
【发布时间】:2011-09-11 01:12:57
【问题描述】:

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

如何使用 PHP(甚至 Java 或 C#)安全地提取嵌入在公钥中的名称/城市信息? 希望以我确切知道这些字段的方式进行操作是(即不盲目抓取文字,而是知道哪个字符串是城市,哪个是名字)

澄清一下:我没有私钥或证书文件。我目前对签名或加密任何东西都不感兴趣,我只想在不使用正则表达式之类的笨拙方法的情况下提取 pubkey 中的明文。

更新:这是来自我的一个 APK 的示例(base64 编码)公钥

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

【问题讨论】:

  • 你能发布一个“由此产生的二进制公钥文件”的例子吗?使用 Base-64 编码将其转换为可发布的文本。
  • @FlyingStreudel - 正则表达式在许多情况下肯定很有用,但我认为它不适合这项任务:P
  • @erickson - 帖子已更新。我使用此站点将其转换为二进制文件:motobit.com/util/base64-decoder-encoder.asp
  • 您是否 100% 确定您的意思是说名称/城市数据“嵌入在公钥中”?我敢打赌,您真正追求的是 X509 证书,其中包含密钥 元数据。
  • Colin 这对我来说就像一个完整的 x509 证书。将 base 64 字符串粘贴到:redkestrel.co.uk/cgi/decodeCert.cgi

标签: c# java php android cryptography


【解决方案1】:

您输入的字符串是基于 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
    }
}
}

【讨论】:

  • 这是完美的 :) 在被告知我实际上有一个证书后,我想出了一个类似的 PHP 解决方案来使用 $dataAsArray = openssl_x509_parse(openssl_x509_read($pemFormattedCertString)); 转储数据
【解决方案2】:

“由此产生的二进制公钥文件”是 X.509 证书。

几乎所有平台都支持读取 X.509 证书并从中创建结构,您可以从中可靠地提取“主题名称”以及通常包括电子邮件地址或主机名的扩展信息。

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

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

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

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

【讨论】:

    【解决方案3】:

    在 php 中,我不确定,但也许 this function 可能是你的朋友。如果您正在使用证书,那么有一个whole section 的 ssl 相关功能可能会派上用场。

    【讨论】:

    • 也许吧,但我只有公钥,没有完整的证书。我早些时候浏览了该功能列表,但找不到任何我想要的特别想要的东西。也许我错过了什么?
    猜你喜欢
    • 2011-07-31
    • 1970-01-01
    • 2018-11-27
    • 1970-01-01
    • 2013-03-10
    • 2012-01-02
    • 2016-06-26
    • 2018-02-28
    • 1970-01-01
    相关资源
    最近更新 更多