Note that there are some explanatory texts on larger screens.

plurals
  1. PORSA Encryption issue between C# and Java using Bouncy Castle
    primarykey
    data
    text
    <p>I'm facing a couple of issues with a Java app and another in C#. Here is the thing. There's a server application that receives request through HTTP, process it and sends back the response. This server is writting in Java with Bouncy Castle and we use PKI to encrypt sensitive data in the request. We have many operations that the server recognizes and one of the them is used to generate the the public and private keys used to exchange with the clients. Each client has a unique ID, so when this operation named GetEncryptionKey is executed, it generates the private key and save it locally in the server and generates the public key which is sent back in PEM format, like this:</p> <pre><code>encryptionKey=-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAon1WDHdarN7yq0UOevzW 5PiFsSC8bEkTUOZ6X3RIth+RCU42pUj/Z8fp9T8rbWp8CqbhlFDxU4c+YucpGljC 7A10nkrPoBT0lpHEuXJiSgx+9qqsyo9q6GddhOpdMa+Z6VCfI+JCM3kdJNMH3r+o i+WLPHLB8lxnfT2CHyZVQGhkzrH9fk1XhdenXxjtPGpwYBOsUZUwRt8EeW6JUwSI mKXiXag0IViEcyAa2BvProkxklbQB3BczLHdXjIDwnE6u1aMA7pYPSkBtY6tuQ0F 5sNWXHsaKWON33MnbhlM7sieYDi9L4dWksala/m/mdIeHIXzX4ZCYdOhayWWKZ1N HwIDAQAB -----END PUBLIC KEY----- </code></pre> <p>This is working ok. The code used to generate the key is the following one:</p> <pre><code>private void getEncryptedKey() throws GWTranException { PEMWriter pemWriter; Security.addProvider(new BouncyCastleProvider()); KeyPair keyPair = null; KeyPairGenerator keyPairGenerator = null; try { keyPairGenerator = KeyPairGenerator.getInstance("RSA"); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } keyPairGenerator.initialize(2048); keyPair = keyPairGenerator.generateKeyPair(); StringWriter writer = new StringWriter(); try { pemWriter = new PEMWriter(new PrintWriter(writer)); pemWriter.writeObject(keyPair.getPublic()); pemWriter.flush(); String pem = writer.toString(); savePrivateKey(keyPair, pem); // save the private key locally } catch (IOException e) { e.printStackTrace(); } } </code></pre> <p>Now I have a client written in C# that connects to the server, retrieves the Public Key sent in the response and use it to encrypt a string that will travel encrypted. This is the .NET code (very simple, as I'm just testing the functionality):</p> <pre><code>private string EncryptDataWithRSA(string data) { string cryptedData = string.Empty; RsaKeyParameters rsaParams; using (var reader = new StringReader(txtKey.Text)) { rsaParams = (RsaKeyParameters)new PemReader(reader).ReadObject(); reader.Close(); } IAsymmetricBlockCipher eng = new RsaEngine(); eng = new OaepEncoding(eng); eng.Init(true, rsaParams); var dataBytes = Encoding.UTF8.GetBytes(data); var cryptedDataBytes = eng.ProcessBlock(dataBytes, 0, dataBytes.Length); cryptedData = Convert.ToBase64String(cryptedDataBytes); return cryptedData; } </code></pre> <p>Everything looks nice but the problem is that when the server (Java app) tries to decrypt the data I get an exception:</p> <pre><code>javax.crypto.BadPaddingException: data hash wrong at org.bouncycastle.jcajce.provider.asymmetric.rsa.CipherSpi.engineDoFinal(Unknown Source) at javax.crypto.Cipher.doFinal(DashoA13*..) at com.verifone.gateway.security.RSAEncryptUtil.decrypt(RSAEncryptUtil.java:127) at com.verifone.gateway.security.RSAEncryptUtil.decrypt(RSAEncryptUtil.java:152) at com.verifone.gateway.preonline.PreOnlineJob.decryptData(PreOnlineJob.java:1661) at com.verifone.gateway.preonline.PreOnlineJob.extractCardData(PreOnlineJob.java:989) at com.verifone.gateway.preonline.PreOnlineJob.run(PreOnlineJob.java:288) at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) at java.util.concurrent.FutureTask$Sync.innerRun(Unknown Source) at java.util.concurrent.FutureTask.run(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) at java.lang.Thread.run(Unknown Source) </code></pre> <p>This is working fine with another client writting in iOS but I don't have access to the source code. I'm writting a simulator in .NET but I'm not being able to get the information decrypted correctly. On the server side this is part of the code used to decrypt the data:</p> <pre><code>public static byte[] decrypt(byte[] text, PrivateKey key) throws Exception { byte[] dectyptedText = null; try { // decrypt the text using the private key Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPPadding"); cipher.init(Cipher.DECRYPT_MODE, key); dectyptedText = cipher.doFinal(text); } catch (Exception e) { //_log.error(e, e); throw e; } return dectyptedText; } </code></pre> <p>I'm out of ideas, I've tried everything. Do you see something I don't? Thanks for your help.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload