'Struggling to use C# RSA in Java
I'm trying to replicate an existing C# application, part of which encrypts some data using a key.
Simple example:
using System;
using System.Security.Cryptography;
using System.Text;
public class Program {
private static string xmlKey = "<RSAKeyValue><Modulus>{REDACTED MODULUS}</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";
public static void Main() {
RSACryptoServiceProvider cipher = new RSACryptoServiceProvider();
cipher.FromXmlString(xmlKey);
Console.WriteLine("KeyExchangeAlgorithm: " + cipher.KeyExchangeAlgorithm);
byte[] input = Encoding.UTF8.GetBytes("test");
byte[] output = cipher.Encrypt(input, true);
Console.WriteLine("Output: " + Convert.ToBase64String(output));
}
}
Which outputs:
KeyExchangeAlgorithm: RSA-PKCS1-KeyEx
Output: {THE ENCRYPTED OUTPUT}
I've replicated this in Java with the following, but while it runs ok, the downstream system can't decrypt the data, so I've done something wrong
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.security.KeyFactory;
import java.security.PublicKey;
import java.security.spec.KeySpec;
import java.security.spec.RSAPublicKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import javax.crypto.Cipher;
public class Program {
// I tried "RSA/ECB/PKCS1Padding" but got "java.security.NoSuchAlgorithmException: RSA/ECB/PKCS1Padding KeyFactory not available at java.base/java.security.KeyFactory.<init>(KeyFactory.java:138)"
private static final String ALGORITHM = "RSA";
private static final String MODULUS = "{REDACTED MODULUS}";
private static final String EXPONENT = "AQAB";
// Converted from XML using
// https://superdry.apphb.com/tools/online-rsa-key-converter
private static final String PEM_KEY = "{REDACTED PEM KEY}";
public static void main(final String[] args) throws Exception {
final Cipher cipher = Cipher.getInstance(ALGORITHM);
final PublicKey key = KeyFactory.getInstance(ALGORITHM).generatePublic(getX509Key());
cipher.init(Cipher.ENCRYPT_MODE, key);
System.out.println("Algorithm: " + cipher.getAlgorithm());
final byte[] input = "test".getBytes(StandardCharsets.UTF_8);
final byte[] output = cipher.doFinal(input);
System.out.println("Output: " + Base64.getEncoder().encodeToString(output));
}
private static KeySpec getRSAKey() throws Exception {
return new RSAPublicKeySpec(base64ToInt(MODULUS), base64ToInt(EXPONENT));
}
private static BigInteger base64ToInt(final String str) {
return new BigInteger(1, Base64.getDecoder().decode(str.getBytes()));
}
private static KeySpec getX509Key() throws Exception {
return new X509EncodedKeySpec(Base64.getDecoder().decode(PEM_KEY));
}
}
Can anyone advise what I've done wrong, please?
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
