【问题标题】:Loading RSA private key加载 RSA 私钥
【发布时间】:2015-08-07 11:50:00
【问题描述】:

我正在尝试在 javacard 中加载私钥(在外部应用程序中使用 RSA 生成)。我编写了一些普通的 java 代码来生成密钥对并打印私钥的指数和模数:

public class Main {

public static void main(String[] args) throws NoSuchAlgorithmException {
    KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
    keyGen.initialize(512);
    KeyPair kp = keyGen.generateKeyPair();
    RSAPrivateKey privateKey = (RSAPrivateKey) kp.getPrivate();
    BigInteger modulus = privateKey.getModulus();
    BigInteger exponent = privateKey.getPrivateExponent();

    System.out.println(Arrays.toString(modulus.toByteArray()));
    System.out.println(Arrays.toString(exponent.toByteArray()));
}

}

然后我将字节数组复制到 javacard 代码中

        try {
            RSAPrivateKey rsaPrivate = (RSAPrivateKey) KeyBuilder.buildKey(KeyBuilder.TYPE_RSA_PRIVATE, KeyBuilder.LENGTH_RSA_512, false);

            byte[] exponent = new byte[]{113, 63, 80, -115, 103, 13, -90, 75, 85, -31, 83, 84, -15, -8, -73, -68, -67, -27, -114, 48, -103, -10, 27, -77, -27, 70, 61, 102, 17, 36, 0, -112, -10, 111, 40, -117, 116, -120, 76, 35, 54, -109, 115, 70, -11, 118, 92, -43, -15, -38, -67, 112, -13, -115, 7, 65, -41, 89, 127, 62, -48, -66, 8, 17};
            byte[] modulus = new byte[]{0, -92, -30, 28, -59, 41, -57, 95, -61, 2, -50, -67, 0, 6, 67, -13, 22, 61, -96, -15, -95, 20, -86, 113, -31, -91, -92, 77, 124, 26, -67, -24, 40, -42, -41, 115, -66, 109, -115, -111, -6, 33, -51, 63, -72, 113, -36, 22, 99, 116, 18, 108, 106, 97, 95, -69, -118, 49, 9, 83, 67, -43, 50, -36, -55};
            rsaPrivate.setExponent(exponent, (short) 0, (short) exponent.length);
            rsaPrivate.setModulus(modulus, (short) 0, (short) modulus.length);
        }
        catch (Exception e) {
            short reason = 0x88;
            if (e instanceof CryptoException)
                reason = ((CryptoException)e).getReason();
            ISOException.throwIt(reason);
        }

现在由于某种原因,在使用原因 1 设置模数时会抛出 CryptoException。根据 API,这意味着 CryptoException.ILLEGAL_VALUE if the input modulus data length is inconsistent with the implementation or if input data decryption is required and fails.

我真的不知道为什么会失败。在此项目中不支持在卡上生成密钥。

而且我知道 512 位不再安全,它只是用于测试目的。最终会被2048位替代。

【问题讨论】:

  • 你试过这样的事情吗?获取 keyBytes: byte[] keyEncodedBytes = privateKey.getEncoded() 将 pkcs11 提供程序关联到 javacard 然后: KeyFactory keyFactory = KeyFactory.getInstance("RSA", pkcs11Provider); PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec (key); PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
  • @Egl 我想重建 javacard 上的私钥。你说的课程在上面不可用。
  • 请注意,512 位密钥不再安全。您至少需要 1024 位才能被认为是安全的。

标签: rsa javacard


【解决方案1】:

我发现 RSAPrivateKey api 需要无符号值,而 BigInteger 的 toByteArray 返回签名版本。这篇文章(BigInteger to byte[])帮助我弄清楚我可以简单地删除模字节数组中的前导零字节。现在一切正常。

【讨论】:

  • 这里的 API 定义不足。它说该值应该是“大端”和“右对齐”,但它没有明确指定它应该是无符号的(或不是)。一般来说,非对称协处理器只会处理正数,所以无符号确实更有意义。但原则上,如果 API 设计被认为是领先的,则实现可能不兼容。
猜你喜欢
  • 2015-07-22
  • 1970-01-01
  • 2018-09-22
  • 2011-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-25
  • 2013-04-20
相关资源
最近更新 更多