-1

I need to translate the below C# codes into Java, however, I could not find any Java equivalent to the Rfc2898DerivedBytes and Rijndael of C#.

    private static string Encrypt(string sData, string sEncryptionKey)
{
    string str = null;
    string str2;
    try
    {
        Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(sEncryptionKey, 8);
        Rijndael rijndael = Rijndael.Create();
        rijndael.IV = bytes.GetBytes(rijndael.BlockSize / 8);
        rijndael.Key = bytes.GetBytes(rijndael.KeySize / 8);
        byte[] buffer = Encoding.Unicode.GetBytes(sData);
        using (MemoryStream stream = new MemoryStream())
        {
            using (CryptoStream stream2 = new CryptoStream(stream, rijndael.CreateEncryptor(), CryptoStreamMode.Write))
            {
                stream.Write(bytes.Salt, 0, bytes.Salt.Length);
                stream2.Write(buffer, 0, buffer.Length);
                stream2.Close();
                str = Convert.ToBase64String(stream.ToArray());
                str2 = str;
            }
        }
    }
    catch (Exception exception)
    {
       System.out.println(exception.getMessage());
    }
    return str2;

}

[Update]

I need to use this function to encrypt the password for new created user, and the encrypted password should also be correctly decrypted by other invoker including C#.

I follow the documents which list in the comments and answer, and try to write below simply sample for quickly verification.

public class testEncrypt {
public static void main(String[] args) throws Exception {

    SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");

    char[] password = "passkey".toCharArray();

    SecureRandom random = new SecureRandom();
    byte[] salt = new byte[8];
    random.nextBytes(salt);

    KeySpec spec = new PBEKeySpec(password, salt, 1000, 256); 
    SecretKey tmp = factory.generateSecret(spec);
    SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES");

    Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
    cipher.init(Cipher.ENCRYPT_MODE, secret);
    AlgorithmParameters params = cipher.getParameters();
    byte[] iv = params.getParameterSpec(IvParameterSpec.class).getIV();
    byte[] ciphertext = cipher.doFinal("301a7fed-54e4-4ae2-9b4d-6db057f75c91".getBytes("UTF-8"));

    System.out.println(ciphertext.length);

}

}

However, the length of the ciphertext is 48, but actually in C#, it looks like this format

WHUNV5xrsfETEiCwcT0M731+Ak1jibsWEodJSaBraP1cmmkS1TpGWqwt/6p/a7oy8Yq30ImZPbFF+Y0JNLa3Eu2UGuazZtuhEepUIIdaDEtA2FO0JYIj2A==

total 120 characters.

Is there something wrong with the code?

SUT
  • 384
  • 1
  • 7
  • 23
  • 1
    You may find [Java equivalent of C#'s Rfc2898DerivedBytes](http://stackoverflow.com/q/1012363/1048330) useful. Also check [Java Rfc2898DeriveBytes](http://www.jmedved.com/2010/05/java-rfc2898derivebytes/) – tenorsax Jul 28 '12 at 03:30
  • Look here: http://stackoverflow.com/questions/1012363/java-equivalent-of-cs-rfc2898derivedbytes I believe Rijndael is just AES http://java.sun.com/developer/technicalArticles/Security/AES/AES_v1.html – Neil Jul 28 '12 at 04:18

1 Answers1

5

RFC2898 is the official name for PBKDF2 (Password Based Key Derivation Function).

This question seems to use the SecretKeyFactory class for PBKDF2.

Password Verification with PBKDF2 in Java

If you cannot find any implementation that you are satisfied with, I suggest you take a look at my question where I used a few classes from BouncyCastle (for C#, but should work for Java) and created the algorithm. I had to create this for C# because there was no Rfc2898DeriveBytes for the .NET Compact Framework.

This question should definitely help you too!

You can also find an implementation here that was done by someone who stumbled across your same problem.

Also to answer the second part of your question,

Rijndael doesn't differ much from AES. To quote this webpage

Namely, Rijndael allows for both key and block sizes to be chosen independently from the set of { 128, 160, 192, 224, 256 } bits. (And the key size does not in fact have to match the block size). However, FIPS-197 specifies that the block size must always be 128 bits in AES, and that the key size may be either 128, 192, or 256 bits.

Rijndael algorithm was chosen by the NIST to be the Advanced Encryption algorithm.

So you can use the AES algorithm in Java.

Community
  • 1
  • 1
Ranhiru Jude Cooray
  • 19,542
  • 20
  • 83
  • 128
  • Thanks for your answer, but even I know the encrypt algorithm is rijndael/AES and how to use Java to encrypt data with AES, I've still no idea about how to translate the original C# codes, especially the rijndael declaring parts. Currently, I've finished translate Rfc2898DeriveBytes in Java. Could you please give me more information about how to translate the remain parts? Thanks – SUT Aug 01 '12 at 06:36
  • You are not going to be able to convert the code line by line to Java mainly because there's no `CryptoStream` class in Java. Take a look at this [question](http://stackoverflow.com/questions/4599113/encrypting-and-decrypting-string-using-a-java-equilavent-of-the-c-sharp-cryptost) as well. – Ranhiru Jude Cooray Aug 01 '12 at 10:53
  • Thanks for your reply. I have rewritten the whole Rfc2898DeriveBytes class in Java, and use java's build AES encryption method, however, it still not works for me. For example, IV's length is limited to 16 in Java. Could you please provide some working code samples for the 150 reputation.:) – SUT Aug 03 '12 at 03:44
  • 2
    I'm sorry if this sounds rude but please don't attempt building cryptographic systems if you don't have thorough knowledge about it. If you are dealing with sensitive customer information, please put a lot of effort and time into learning what is a cryptographic algorithm, what is an IV, what is the block size, why you use PBKDF2 etc. Anyway, first test whether `Rfc2898DeriveBytes` is working properly. Also if the IV is limited to 16 in Java, you will have to use the block size of 128 bits. Update your answer with the current code that you have come up with and any issues that you are facing. – Ranhiru Jude Cooray Aug 03 '12 at 04:37
  • To add to the comment above, better yet, don't build your own crypto system if you can afford to. Use something that's already being built, tried and tested. It doesn't matter how hard you learn, one subtle mistake is all it takes to break it. On the other hand systems like MS Enterprise Library, ASP .NET Membership, Apache Shiro or Spring Security are being used in the industry and their bugs are reported and fixed. – Ranhiru Jude Cooray Sep 16 '12 at 14:19