【问题标题】:C++/Openssl Get RSA key from encoded bytes (encoded by java)C++/Openssl 从编码字节中获取 RSA 密钥(由 java 编码)
【发布时间】:2017-07-08 17:41:38
【问题描述】:

有人知道我如何在 C++ 中从编码的字节数组创建 RSA 密钥吗?

我的问题是我尝试开发一个 C++ 客户端,它与用 Java 编码的服务器交互。 在 Java 中,客户端接收编码为字节数组的 rsa 密钥,将其解码为 RSA RSAPublicKey 并使用此密钥加密消息。

java 服务器/客户端代码:

public static PublicKey decodePublicKey(byte[] p_75896_0_)
{
    try
    {
        X509EncodedKeySpec var1 = new X509EncodedKeySpec(p_75896_0_);
        KeyFactory var2 = KeyFactory.getInstance("RSA");
        return var2.generatePublic(var1);
    }
    catch (NoSuchAlgorithmException var3)
    {
        ;
    }
    catch (InvalidKeySpecException var4)
    {
        ;
    }

    field_180198_a.error("Public key reconstitute failed!");
    return null;
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

this.publicKey = CryptManager.decodePublicKey(data.readByteArray());

之后,客户用他的密钥做一些加密工作。

密钥是这样发送的:

public static final KeyPair keys;
static
{
    try
    {
        KeyPairGenerator generator = KeyPairGenerator.getInstance( "RSA" );
        generator.initialize( 1024 );
        keys = generator.generateKeyPair();
    } catch ( NoSuchAlgorithmException ex )
    {
        throw new ExceptionInInitializerError( ex );
    }
}

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
byte[] pubKey = keys.getPublic().getEncoded();
writeBytes(pubKey);

我的问题是如何从 C++ 中的字节数组中获取密钥。

更新: 我目前正在处理此代码:

    char* publicKey = ...
    int publicKeyLength = 162;
    EVP_PKEY* key = EVP_PKEY_new();

    if(d2i_PUBKEY(&key, (const unsigned char**) &publicKey, publicKeyLength) != 0){
        logError("Problem!");
    }
    logMessage("Key: "+to_string((uint64_t) (void*) key));

我现在的问题是我在第三行有一个 SIGSEGV 错误并且不知道这门课程是什么。那么密钥应该是有效的。

【问题讨论】:

  • 您是否选择了图书馆来执行此操作?否则,这个问题真的很宽泛,因为有很多方法可以做到这一点。
  • 我更喜欢 OpenSSL。好吧,但如果你有更好的解决方案或库,我会看看这个。
  • 好的,那么您打开API documentation 看看哪些功能在这种情况下可能有用吗? PEM_read_bio_PrivateKey 可能是个不错的开始。
  • 是的,但问题是我没有带密钥的文件/字符串。我应该有原始编码字节
  • 您不需要文件。 BIO 有一个选项。

标签: java c++ encryption cryptography


【解决方案1】:

Java 为公钥返回的是一个 SubjectPublicKeyInfo 结构,它不仅包含公钥的(PKCS#1 编码)值,还包含密钥标识符等。

因此,要对此进行解码,您必须在您喜欢的搜索引擎中输入“decode SubjectPublicKeyInfo openssl”。然后你会发现(经过一些滚动)来自here的以下信息:

d2i_PUBKEY() and i2d_PUBKEY() decode and encode an EVP_PKEY structure
using SubjectPublicKeyInfo format. They otherwise follow the conventions
of other ASN.1 functions such as d2i_X509().

显然你需要解码算法。


请注意,openssl 是 C,因此在解码内容时要小心缓冲区溢出。我宁愿拥有一个用于安全软件的 1024 位 RSA 密钥,也不愿拥有一个充满缓冲区溢出的软件的 2048 位密钥。

不用说您需要在导入之前信任公钥。将其称为公钥基础设施 (PKI) 是有原因的。

【讨论】:

  • 感谢您的详细回答,我在家时会再试一次。我已经用这个方法试过了,但每次都会出错,所以我认为 java 不会导出 SubjectPublicKeyInfo 结构中的密钥。
  • 确实如此。确保以二进制模式打开文件。
猜你喜欢
  • 2016-05-18
  • 1970-01-01
  • 2015-02-03
  • 2014-01-23
  • 2018-05-31
  • 1970-01-01
  • 1970-01-01
  • 2011-11-05
相关资源
最近更新 更多