Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/321.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# .NET和Java的Rfc2898DeriveBytes生成不同的值_C#_Java_Android_.net - Fatal编程技术网

C# .NET和Java的Rfc2898DeriveBytes生成不同的值

C# .NET和Java的Rfc2898DeriveBytes生成不同的值,c#,java,android,.net,C#,Java,Android,.net,我正在尝试使用Rfc2898DeriveBytes for Android Java和.NET C#framework为加密和解密过程生成密钥 问题是,尽管输入值相同,但在.NET和Java中得到的键不同 .NET代码: private void btnRfc2898DeriveBytes_Click(object sender, EventArgs e) { byte[] salt = new byte[] { 19, 3, 24, 18, 14, 42, 57, 23 };

我正在尝试使用Rfc2898DeriveBytes for Android Java和.NET C#framework为加密和解密过程生成密钥

问题是,尽管输入值相同,但在.NET和Java中得到的键不同

.NET代码:

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));
}
private void btnKey_Click(object sender, EventArgs e)
{
    byte[] salt = new byte[] { 172, 137, 25, 56, 156, 100, 136, 211, 84, 67, 96, 10, 24, 111, 112, 137, 3 };
    int iterations = 1024;
    var rfc2898 = new System.Security.Cryptography.Rfc2898DeriveBytes("_sOme*ShaREd*SecreT", salt, iterations);
    byte[] key = rfc2898.GetBytes(16);
    String keyB64 = Convert.ToBase64String(key);
    txtRfc2898DeriveBytes.Text = keyB64;
}
Java代码(用于android应用程序):

Java解码方法:

String decodeUTF8(byte[] bytes) {
    private final Charset UTF8_CHARSET = Charset.forName("UTF-8");
    return new String(bytes, UTF8_CHARSET);
}
Rfc2898DeriveBytes java类:

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 < 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 > 0) { //if there is some data in buffer
            if (count < 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 < count) {
            int needCount = count - resultOffset;
            this._buffer = this.func();
            if (needCount > 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 <= this._iterationCount; i++) {
            tempHash = this._hmacSha1.doFinal(tempHash);
            for (int j = 0; j < 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 >>> 24), (byte)(i >>> 16), (byte)(i >>> 8), (byte)i };
    }

}
import java.io.UnsupportedEncodingException;
导入java.security.InvalidKeyException;
导入java.security.NoSuchAlgorithmException;
导入javax.crypto.Mac;
导入javax.crypto.spec.SecretKeySpec;
/**
*RFC 2898密码派生与.NET Rfc2898DeriveBytes类兼容。
*/
公共类Rfc2898DeriveBytes{
私人Mac_hmacSha1;
专用字节[]_;
私有整数迭代计数;
专用字节[]_buffer=新字节[20];
私有int _bufferStartIndex=0;
私有int_bufferEndIndex=0;
专用int_块=1;
/**
*创建新实例。
*@param password用于派生密钥的密码。
*@param salt用于派生密钥的密钥salt。
*@param iterations操作的迭代次数。
*找不到@NOSUCHAlgorithException HmacSHA1算法。
*@InvalidKeyException Salt必须为8字节或更多。-或-密码不能为空。
*/
公共Rfc2898DeriveBytes(字节[]密码,字节[]salt,int迭代)抛出NoSuchAlgorithmException,InvalidKeyException{
如果((salt==null)| |(salt.length<8)){抛出新的InvalidKeyException(“salt必须是8字节或更多。”);}
如果(password==null){抛出新的InvalidKeyException(“密码不能为null”);}
这个._salt=盐;
这是。_iterationCount=迭代次数;
这个.hmacSha1=Mac.getInstance(“hmacSha1”);
这个.hmacSha1.init(新的SecretKeySpec(密码,“hmacSha1”);
}
/**
*创建新实例。
*@param password用于派生密钥的密码。
*@param salt用于派生密钥的密钥salt。
*@param iterations操作的迭代次数。
*找不到@NOSUCHAlgorithException HmacSHA1算法。
*@InvalidKeyException Salt必须为8字节或更多。-或-密码不能为空。
*@throws UnsupportedEncodingException不支持UTF-8编码。
*/
公共Rfc2898DeriveBytes(字符串密码,字节[]salt,int迭代)引发InvalidKeyException、NoSuchAlgorithmException、UnsupportedEncodingException{
这(password.getBytes(“UTF8”)、salt、迭代次数);
}
/**
*创建新实例。
*@param password用于派生密钥的密码。
*@param salt用于派生密钥的密钥salt。
*找不到@NOSUCHAlgorithException HmacSHA1算法。
*@InvalidKeyException Salt必须为8字节或更多。-或-密码不能为空。
*@throws UnsupportedEncodingException不支持UTF-8编码。
*/
公共Rfc2898DeriveBytes(字符串密码,字节[]salt)抛出NoSuchAlgorithmException、InvalidKeyException、UnsupportedEncodingException{
这个(密码,salt,0x3e8);
}
/**
*从密码、salt和迭代计数返回伪随机密钥。
*@param count要返回的字节数。
*@返回字节数组。
*/
公共字节[]getBytes(整数计数){
字节[]结果=新字节[计数];
int resultofset=0;
int bufferCount=this.\u BUFFERENDIX-this.\u bufferStartIndex;
如果(bufferCount>0){//如果缓冲区中有一些数据
if(count20){//我们需要一个(或多个)额外的通行证
System.arraycopy(此.u缓冲区,0,result,resultofset,20);
resultofset+=20;
}否则{
System.arraycopy(此.u缓冲区,0,结果,resultOffset,needCount);
这。_bufferStartIndex=needCount;
这个._bufferEndIndex=20;
返回结果;
}
}
返回结果;
}
专用字节[]func(){
this.\hmacSha1.update(this.\u salt,0,this.\u salt.length);
字节[]tempHash=this.\u hmacSha1.doFinal(getBytesFromInt(this.\u块));
这个。hmacSha1.reset();
字节[]finalHash=tempHash;
对于(inti=2;i>>24),(字节)(i>>16),(字节)(i>>8),(字节)i};
}
}
编辑:

我还将其转换为十六进制,但也会得到不同的值

C#功能:

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 < l)
    {
        d = data[i++];
        c[p++] = lookup[d / 0x10];
        c[p++] = lookup[d % 0x10];
    }
    return new string(c, 0, c.Length);
}
公共静态字符串编码(字节[]数据)
{
字符[]查找=新字符[]{'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=新字符[l*2+2];
字节d;c[0]=“0”;c[1]=“x”;
而(i
Java方法:

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 < bytes.length; j++ ) {
        v = bytes[j] & 0xFF;
        hexChars[j * 2] = hexArray[v >>> 4];
        hexChars[j * 2 + 1] = hexArray[v & 0x0F];
    }
    return new String(hexChars);
}
final protected static char[]hexArray=“0123456789ABCDEF.tocharray();
公共静态字符串bytesToHex(字节[]字节){
char[]hexChars=新字符[bytes.length*2];
INTV;
对于(int j=0;j>>4];
hexChars[j*2+1]=hexArray[v&0x0F];
txtRfc2898DeriveBytes.Text = System.Text.Encoding.UTF8.GetString(
    keyGenerator.GetBytes(16));
decodeUTF8(keyGenerator.getBytes(16)
private void btnKey_Click(object sender, EventArgs e)
{
    byte[] salt = new byte[] { 172, 137, 25, 56, 156, 100, 136, 211, 84, 67, 96, 10, 24, 111, 112, 137, 3 };
    int iterations = 1024;
    var rfc2898 = new System.Security.Cryptography.Rfc2898DeriveBytes("_sOme*ShaREd*SecreT", salt, iterations);
    byte[] key = rfc2898.GetBytes(16);
    String keyB64 = Convert.ToBase64String(key);
    txtRfc2898DeriveBytes.Text = keyB64;
}
String password = "_sOme*ShaREd*SecreT";
byte[] salta = new byte[]{-84, -119, 25, 56, -100, 100, -120, -45, 84, 67, 96, 10, 24, 111, 112, -119, 3};
SecretKeyFactory factory = null;
try {
    factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
} catch (NoSuchAlgorithmException e2) {
    e2.printStackTrace();
}
KeySpec spec = new PBEKeySpec(password.toCharArray(), salta, 1024, 128);
SecretKey tmp = null;
try {
    tmp = factory.generateSecret(spec);
} catch (InvalidKeySpecException e2) {
    e2.printStackTrace();
}
SecretKeySpec secret = new SecretKeySpec(tmp.getEncoded(), "AES");
Log.i("The secret Key: " , Base64.encodeToString(secret.getEncoded(), 0 ));