Encrypt and decrypt strings using Java equivalent C # CryptoStream

I am considering developing a Java application for a mobile platform operating system.

I developed an application in C # WPF for a Windows environment. I use crypto stream to encrypt and decrypt a string using the following code. the code below is only encryption

public string encrypt(string encryptionString) { byte[] clearTextBytes = Encoding.UTF8.GetBytes(encryptionString); SymmetricAlgorithm rijn = SymmetricAlgorithm.Create(); MemoryStream ms = new MemoryStream(); byte[] rgbIV = Encoding.ASCII.GetBytes("ryojvlzmdalyglrj"); byte[] key = Encoding.ASCII.GetBytes("hcxilkqbbhczfeultgbskdmaunivmfuo"); CryptoStream cs = new CryptoStream(ms, rijn.CreateEncryptor(key, rgbIV), CryptoStreamMode.Write); cs.Write(clearTextBytes, 0, clearTextBytes.Length); cs.Close(); return Convert.ToBase64String(ms.ToArray()); } 

The encrypted string is stored in an online database. I should be able to do this so that the Java application can read the string from the database and decrypt the string using the same encryption keys from the C # application.

Thank you for your help.

+4
source share
7 answers

Personally, I like BouncyCastle for Java cryptography. This code (using the lightweight BouncyCastle API) should do the trick:

 String decrypt(byte[] cryptoBytes, byte[] key, byte[] iv) { BlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new AESEngine())); cipher.init(false, new ParametersWithIV(new KeyParameter(key), iv)); byte[] out = new byte[cipher.getOutputSize(cryptoBytes.length)]; int offset = cipher.processBytes(cryptoBytes, 0, cryptoBytes.length, out, 0); cipher.doFinal(out, offset); return new String(out); } 

I find the lightweight BouncyCastle API less painful than the JCE vendor stuff, but you can use it as a vendor if you want.

It seems that both .net SymmetricAlgorithm and BC PaddedBufferedBlockCipher by default to populate PKCS7, so you should be fine using the default values.

+6
source

You can check javax.crypto.CipherInputStream and javax.crypto.CipherOutputStream.

http://download.oracle.com/javase/1.5.0/docs/api/javax/crypto/CipherInputStream.html http://download.oracle.com/javase/1.5.0/docs/api/javax/crypto /CipherOutputStream.html

They are used almost exactly the same as your sample above, although the initialization of Cipher objects may be slightly different.

+2
source

I use the following to encrypt between .net and java

In .net I use:

  /// <summary> /// DES Encryption method - used to encryp password for the java. /// </summary> /// <param name="plainText"></param> /// <returns></returns> public string EncryptData(string plainText) { DES des = new DESCryptoServiceProvider(); des.Mode = CipherMode.ECB; des.Padding = PaddingMode.PKCS7; des.Key = Encoding.UTF8.GetBytes(_secretPhrase.Substring(0, 8)); des.IV = Encoding.UTF8.GetBytes(_secretPhrase.Substring(0, 8)); byte[] bytes = Encoding.UTF8.GetBytes(plainText); byte[] resultBytes = des.CreateEncryptor().TransformFinalBlock(bytes, 0, bytes.Length); return Convert.ToBase64String(resultBytes); } /// <summary> /// DES Decryption method - used the decrypt password encrypted in java /// </summary> /// <param name="encryptedText"></param> /// <returns></returns> public string DecryptData(string encryptedText) { DES des = new DESCryptoServiceProvider(); des.Mode = CipherMode.ECB; des.Padding = PaddingMode.PKCS7; des.Key = Encoding.UTF8.GetBytes(_secretPhrase.Substring(0, 8)); des.IV = System.Text.Encoding.UTF8.GetBytes(_secretPhrase.Substring(0, 8)); byte[] bytes = Convert.FromBase64String(encryptedText); byte[] resultBytes = des.CreateDecryptor().TransformFinalBlock(bytes, 0, bytes.Length); return Encoding.UTF8.GetString(resultBytes); } 

and in java I use:

public class CryptoUtil {

 public static final Logger LOG = Logger.getLogger(CryptoUtil.class); private Cipher cipher = null; private SecretKey key = null; // This variable holds a string based on which a unique key will be generated private static final String SECRET_PHRASE = "SECRET PHRASE GOES HERE"; // Charset will be used to convert between String and ByteArray private static final String CHARSET = "UTF8"; // The algorithm to be used for encryption/decryption DES(Data Encryption Standard) private static final String ALGORITHM = "DES"; public CryptoUtil() throws DDICryptoException { try { // generate a key from SecretKeyFactory DESKeySpec keySpec = new DESKeySpec(SECRET_PHRASE.getBytes(CHARSET)); SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(ALGORITHM); key = keyFactory.generateSecret(keySpec); cipher = Cipher.getInstance(ALGORITHM); } catch (Exception e) { LOG.error(e); throw new DDICryptoException(e); } } /** * This method takes a plain text string and returns encrypted string using DES algorithm * @param plainText * @return String * @throws DDICryptoException */ public String encrypt(String plainText) throws DDICryptoException { String encryptedString = null; try { // initializes the cipher with a key. cipher.init(Cipher.ENCRYPT_MODE, key); byte[] plainTextAsUTF8 = plainText.getBytes(CHARSET); // decrypts data in a single-part or multi-part operation byte[] encryptedBytes = cipher.doFinal(plainTextAsUTF8); encryptedString = new sun.misc.BASE64Encoder().encode(encryptedBytes); } catch (Exception e) { LOG.error(e); throw new DDICryptoException(e); } return encryptedString; } /** * This method takes a plain text string and returns encrypted string using DES algorithm * @param encryptedString * @return * @throws DDICryptoException */ public String decrypt(String encryptedString) throws DDICryptoException { String decryptedString = null; try { byte[] decodedString = new sun.misc.BASE64Decoder().decodeBuffer(encryptedString); // initializes the cipher with a key. cipher.init(Cipher.DECRYPT_MODE, key); // decrypts data in a single-part or multi-part operation byte[] decryptedBytes = cipher.doFinal(decodedString); decryptedString = new String(decryptedBytes, CHARSET); } catch (Exception e) { LOG.error(e); throw new DDICryptoException(e); } return decryptedString; } 

}

0
source

I managed to solve the problem. Decryption now works fine. Using the following code

  String plainPassword = ""; try { SecretKeySpec key = new SecretKeySpec("hcxilkqbbhczfeultgbskdmaunivmfuo".getBytes("US-ASCII"), "AES"); IvParameterSpec iv = new IvParameterSpec("ryojvlzmdalyglrj".getBytes("US_ASCII")); Cipher cipher = Cipher.getInsta nce("AES/CBC/PKCS7Padding"); cipher.init(Cipher.DECRYPT_MODE, key, iv); byte[] encoded = cipher.doFinal(Base64.decodeBase64(encryptedPassword.getBytes())); plainPassword = new String(encoded); } catch (Exception ex) { Log.d("Decryption Error", ex.toString()); } return plainPassword; 

Now the problem is encryption. I used the same code, except that I changed the cipher from decryption mode to encryption mode, but for some reason, when I print an encrypted string, it just prints a load of garbage that doesn't look like the string that C # creates. Below is the code for encryption

 public String encrypt(String plainPasword) { String password = ""; try { SecretKeySpec key = new SecretKeySpec("hcxilkqbbhczfeultgbskdmaunivmfuo".getBytes("US-ASCII"), "AES"); IvParameterSpec iv = new IvParameterSpec("ryojvlzmdalyglrj".getBytes("US_ASCII")); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS7Padding"); cipher.init(Cipher.ENCRYPT_MODE, key, iv); byte[] encoded = cipher.doFinal(plainPasword.getBytes()); password = new String(encoded); } catch (Exception ex) { Log.d("Encryption Error", ex.toString()); } return password; } 

Something is wrong with this, I can not figure it out. Thanks

0
source
  StringBuffer strbuf = new StringBuffer(buf.length * 2); int i; for (i = 0; i < buf.length; i++) { if (((int) buf[i] & 0xff) < 0x10) { strbuf.append("0"); } strbuf.append(Long.toString((int) buf[i] & 0xff, 16)); } 

You must encode the resulting byte array before converting it to a string. The code above helped, while my actual encryption function is below.

 public String encrypt(String data) throws Exception{ try { Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding"); Key k = new SecretKeySpec(key.getBytes(), 0, key.length(), "AES"); // Calculate ciphertext size. int blocksize = 16; int ciphertextLength = 0; int remainder = data.getBytes().length % blocksize; if (remainder == 0) { ciphertextLength = data.getBytes().length + blocksize; } else { ciphertextLength = data.getBytes().length - remainder + blocksize; } cipher.init(Cipher.ENCRYPT_MODE, k); byte[] buf = new byte[ciphertextLength]; cipher.doFinal(data.getBytes(), 0, data.length(), buf, 0); StringBuffer strbuf = new StringBuffer(buf.length * 2); int i; for (i = 0; i < buf.length; i++) { if (((int) buf[i] & 0xff) < 0x10) { strbuf.append("0"); } strbuf.append(Long.toString((int) buf[i] & 0xff, 16)); } return strbuf.toString(); } catch (Exception e) { Logger.logException(e); } return null; } 
0
source

See answer No. 5 to the CryptoStream.NET equivalent in Java?



Be sure to read the comments below ...

KeySpec ks = new DESKeySpec("key12345".getBytes("UTF-8")); SecretKey key = SecretKeyFactory.getInstance("DES").generateSecret(ks);
IvParameterSpec iv = new IvParameterSpec( Hex.decodeHex("1234567890ABCDEF".toCharArray()));
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, key, iv);
byte[] decoded = cipher.doFinal(Base64.decodeBase64("B3xogi/Qfsc="));
System.out.println("Decoded: " + new String(decoded, "UTF-8"));

Hope this helps ...
Jk

0
source

Cemeron; Here is a neat code!

I came across an interesting situation when our client gave IV the same thing as a key .

After testing various combinations in which I got an exception for the complement, the solution that worked was

 byte[] iv=new byte[8]; // assuming RC2 System.arraycopy(key.getBytes(), 0, iv, 0, key.getBytes().length > iv.length ? key.getBytes().length); // Now decrypt and hopefully this should work 
-1
source

Source: https://habr.com/ru/post/1334276/