Note that there are some explanatory texts on larger screens.

plurals
  1. PORfc2898DeriveBytes for .NET and Java generate different values
    primarykey
    data
    text
    <p>I'm trying to use Rfc2898DeriveBytes for Android Java and .NET C# framework to generate key for encryption and decryption process. </p> <p>The problem is in spite of that the input values are same, I'm getting different keys in .NET and Java. </p> <p>.NET code:</p> <pre><code>private void btnRfc2898DeriveBytes_Click(object sender, EventArgs e) { byte[] salt = new byte[] { 19, 3, 24, 18, 14, 42, 57, 23 }; Rfc2898DeriveBytes keyGenerator = null; keyGenerator = new Rfc2898DeriveBytes("somestring", salt, 1000); txtRfc2898DeriveBytes.Text = System.Text.Encoding.UTF8.GetString(keyGenerator.GetBytes(16)); } </code></pre> <p>Java Code (used in an android application):</p> <pre><code>byte[] salt = new byte[] { 19, 3, 24, 18, 14, 42, 57, 23 }; Rfc2898DeriveBytes keyGenerator = null; try { keyGenerator = new Rfc2898DeriveBytes("somestring", salt, 1000); } catch (InvalidKeyException e1) { e1.printStackTrace(); } catch (NoSuchAlgorithmException e1) { e1.printStackTrace(); } catch (UnsupportedEncodingException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } Log.i("key = ", decodeUTF8(keyGenerator.getBytes(16))); </code></pre> <p>Java Decode Method:</p> <pre><code>String decodeUTF8(byte[] bytes) { private final Charset UTF8_CHARSET = Charset.forName("UTF-8"); return new String(bytes, UTF8_CHARSET); } </code></pre> <p>Rfc2898DeriveBytes java class:</p> <pre><code>import java.io.UnsupportedEncodingException; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; /** * RFC 2898 password derivation compatible with .NET Rfc2898DeriveBytes class. */ public class Rfc2898DeriveBytes { private Mac _hmacSha1; private byte[] _salt; private int _iterationCount; private byte[] _buffer = new byte[20]; private int _bufferStartIndex = 0; private int _bufferEndIndex = 0; private int _block = 1; /** * Creates new instance. * @param password The password used to derive the key. * @param salt The key salt used to derive the key. * @param iterations The number of iterations for the operation. * @throws NoSuchAlgorithmException HmacSHA1 algorithm cannot be found. * @throws InvalidKeyException Salt must be 8 bytes or more. -or- Password cannot be null. */ public Rfc2898DeriveBytes(byte[] password, byte[] salt, int iterations) throws NoSuchAlgorithmException, InvalidKeyException { if ((salt == null) || (salt.length &lt; 8)) { throw new InvalidKeyException("Salt must be 8 bytes or more."); } if (password == null) { throw new InvalidKeyException("Password cannot be null."); } this._salt = salt; this._iterationCount = iterations; this._hmacSha1 = Mac.getInstance("HmacSHA1"); this._hmacSha1.init(new SecretKeySpec(password, "HmacSHA1")); } /** * Creates new instance. * @param password The password used to derive the key. * @param salt The key salt used to derive the key. * @param iterations The number of iterations for the operation. * @throws NoSuchAlgorithmException HmacSHA1 algorithm cannot be found. * @throws InvalidKeyException Salt must be 8 bytes or more. -or- Password cannot be null. * @throws UnsupportedEncodingException UTF-8 encoding is not supported. */ public Rfc2898DeriveBytes(String password, byte[] salt, int iterations) throws InvalidKeyException, NoSuchAlgorithmException, UnsupportedEncodingException { this(password.getBytes("UTF8"), salt, iterations); } /** * Creates new instance. * @param password The password used to derive the key. * @param salt The key salt used to derive the key. * @throws NoSuchAlgorithmException HmacSHA1 algorithm cannot be found. * @throws InvalidKeyException Salt must be 8 bytes or more. -or- Password cannot be null. * @throws UnsupportedEncodingException UTF-8 encoding is not supported. */ public Rfc2898DeriveBytes(String password, byte[] salt) throws NoSuchAlgorithmException, InvalidKeyException, UnsupportedEncodingException { this(password, salt, 0x3e8); } /** * Returns a pseudo-random key from a password, salt and iteration count. * @param count Number of bytes to return. * @return Byte array. */ public byte[] getBytes(int count) { byte[] result = new byte[count]; int resultOffset = 0; int bufferCount = this._bufferEndIndex - this._bufferStartIndex; if (bufferCount &gt; 0) { //if there is some data in buffer if (count &lt; bufferCount) { //if there is enough data in buffer System.arraycopy(this._buffer, this._bufferStartIndex, result, 0, count); this._bufferStartIndex += count; return result; } System.arraycopy(this._buffer, this._bufferStartIndex, result, 0, bufferCount); this._bufferStartIndex = this._bufferEndIndex = 0; resultOffset += bufferCount; } while (resultOffset &lt; count) { int needCount = count - resultOffset; this._buffer = this.func(); if (needCount &gt; 20) { //we one (or more) additional passes System.arraycopy(this._buffer, 0, result, resultOffset, 20); resultOffset += 20; } else { System.arraycopy(this._buffer, 0, result, resultOffset, needCount); this._bufferStartIndex = needCount; this._bufferEndIndex = 20; return result; } } return result; } private byte[] func() { this._hmacSha1.update(this._salt, 0, this._salt.length); byte[] tempHash = this._hmacSha1.doFinal(getBytesFromInt(this._block)); this._hmacSha1.reset(); byte[] finalHash = tempHash; for (int i = 2; i &lt;= this._iterationCount; i++) { tempHash = this._hmacSha1.doFinal(tempHash); for (int j = 0; j &lt; 20; j++) { finalHash[j] = (byte)(finalHash[j] ^ tempHash[j]); } } if (this._block == 2147483647) { this._block = -2147483648; } else { this._block += 1; } return finalHash; } private static byte[] getBytesFromInt(int i) { return new byte[] { (byte)(i &gt;&gt;&gt; 24), (byte)(i &gt;&gt;&gt; 16), (byte)(i &gt;&gt;&gt; 8), (byte)i }; } } </code></pre> <p>Edit:</p> <p>I also convert it to Hex, but getting different values also. </p> <p>C# function:</p> <pre><code>public static String encode(byte[] data) { char[] lookup = new char[] { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; int i = 0, p = 2, l = data.Length; char[] c = new char[l * 2 + 2]; byte d; c[0] = '0'; c[1] = 'x'; while (i &lt; l) { d = data[i++]; c[p++] = lookup[d / 0x10]; c[p++] = lookup[d % 0x10]; } return new string(c, 0, c.Length); } </code></pre> <p>Java method:</p> <pre><code>final protected static char[] hexArray = "0123456789ABCDEF".toCharArray(); public static String bytesToHex(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; int v; for ( int j = 0; j &lt; bytes.length; j++ ) { v = bytes[j] &amp; 0xFF; hexChars[j * 2] = hexArray[v &gt;&gt;&gt; 4]; hexChars[j * 2 + 1] = hexArray[v &amp; 0x0F]; } return new String(hexChars); } </code></pre> <p>What I'm doing wrong :( ?</p>
    singulars
    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.
    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