Ключ RSA (формат XML), совместимый с .Net

Как сгенерировать ключи RSA на основе xml (частные, общедоступные), которые должны быть совместимы со средой .NET. Я пробовал модуль phpseclib на PHP. Но он несовместим с .NET. Пожалуйста, предложите мне какой-либо способ сгенерировать ключи RSA на основе xml в Java? На самом деле я работаю над системой на базе Linux. Используя эти ключи, я собираюсь выполнить операцию шифрования и дешифрования. Нравиться

<RSAKeyValue>
    <Modulus>4hjg1ibWXHIlH...ssmlBfMAListzrgk=</Modulus>
    <Exponent>AQAB</Exponent>
    <P>8QZCtrmJcr9uW7VRex+diH...jLHV5StmuBs1+vZZAQ==</P>
    <Q>8CUvJTv...yeDszMWNCQ==</Q>
    <DP>elh2Nv...cygE3657AQ==</DP>
    <DQ>MBUh5XC...+PfiMfX0EQ==</DQ>
    <InverseQ>oxvsj4WCbQ....LyjggXg==</InverseQ>
    <D>KrhmqzAVasx...uxQ5VGZmZ6yOAE=</D>
</RSAKeyValue>

person sat    schedule 20.09.2012    source источник
comment
Вы хотите сказать, что они проверены на разных XSD?   -  person Chris    schedule 20.09.2012


Ответы (2)


В Java нет поддержки для этого из коробки, но это все еще довольно тривиально. Во-первых, вы создаете пару ключей RSA с помощью JCA KeyPairGenerator.

Затем вам нужно привести закрытый ключ к соответствующему интерфейсу (мы используем RSAPrivateCrtKey вместо RSAPrivateKey, чтобы мы могли получить доступ к частям CRT) и использовать кодек Apache Commons для кодирования Base64.

public static void main(String[] args) throws Exception {
    KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");
    KeyPair keyPair = keyPairGen.genKeyPair();
    RSAPrivateCrtKey privKey = (RSAPrivateCrtKey) keyPair.getPrivate();

    BigInteger n = privKey.getModulus();
    BigInteger e = privKey.getPublicExponent();
    BigInteger d = privKey.getPrivateExponent();
    BigInteger p = privKey.getPrimeP();
    BigInteger q = privKey.getPrimeQ();
    BigInteger dp = privKey.getPrimeExponentP();
    BigInteger dq = privKey.getPrimeExponentQ();
    BigInteger inverseQ = privKey.getCrtCoefficient(); 

    StringBuilder builder = new StringBuilder();
    builder.append("<RSAKeyValue>\n");
    write(builder, "Modulus", n);
    write(builder, "Exponent", e);
    write(builder, "P", p);
    write(builder, "Q", q);
    write(builder, "DP", dp);
    write(builder, "DQ", dq);
    write(builder, "InverseQ", inverseQ);
    write(builder, "D", d);
    builder.append("</RSAKeyValue>");

    System.out.println(builder.toString());
}

private static void write(StringBuilder builder, String tag, BigInteger bigInt) {
    builder.append("\t<");
    builder.append(tag);
    builder.append(">");
    builder.append(encode(bigInt));
    builder.append("</");
    builder.append(tag);
    builder.append(">\n");
}

private static String encode(BigInteger bigInt) {
    return new String(Base64.encodeInteger(bigInt), "ASCII");
}

Вы можете использовать правильный XML API, если хотите, но я не чувствовал веских причин не использовать StringBuilder в этом случае. Кроме того, не стесняйтесь встраивать экземпляры BigInteger. Я объявил их как переменные, чтобы сделать сопоставление между методами Java и элементами XML более очевидным.

person David Grant    schedule 20.09.2012
comment
Вы использовали Bouncy Castle для кодировки Base64? - person Maarten Bodewes; 20.09.2012
comment
ОК, уже проголосовали, но оператора импорта не было :) - person Maarten Bodewes; 21.09.2012
comment
Я все же упомянул во втором параграфе;) - person David Grant; 21.09.2012
comment
Баггер, этого не видел. Я бы сразу пошла в оптику, а здесь 23:25 :) - person Maarten Bodewes; 21.09.2012
comment
Спасибо .. Очень полезно. - person sat; 21.09.2012
comment
Мне кажется, что метод кодирования не подходит. encodeInteger () должен возвращать массив байтов, так почему вы создаете из него String? Разве вы не должны кодировать результирующую строку base64? - person TimK; 09.08.2013

Если кто-то хочет сделать обратную операцию - возьмите RSAPrivateCrtKey по xml-файлу, не забудьте создать экземпляр BigInteger с положительным параметром signum.

new BigInteger(1, Base64.getDecoder().decode(encodedBigInteger));

Это позволяет избежать потенциального исключения

java.security.SignatureException: Could not sign data
    at sun.security.rsa.RSASignature.engineSign(RSASignature.java:178)
    at java.security.Signature$Delegate.engineSign(Signature.java:1207)
    at java.security.Signature.sign(Signature.java:579)
    ... more
Caused by: javax.crypto.BadPaddingException: Message is larger than modulus
    at sun.security.rsa.RSACore.parseMsg(RSACore.java:214)
    at sun.security.rsa.RSACore.crtCrypt(RSACore.java:166)
    at sun.security.rsa.RSACore.rsa(RSACore.java:122)
    at sun.security.rsa.RSASignature.engineSign(RSASignature.java:175)
    ... 6 more
person Vsevolod Kaimashnikov    schedule 10.01.2019