Rfc2898DeriveBytes解密如何通过java实现

原文 Rfc2898DeriveBytes解密如何通过java实现

这个找了半天,还是不太懂,密码一点不懂,直接上来问了
Rfc2898DeriveBytes对应的是PBKDF2WithHmacSHA1,Rfc2898DeriveBytes默认的迭代次数为1000,剩下的不知道了
以下为C#代码 C# code
public byte[] DecryptData(byte[] data) { AesManaged managed = null; MemoryStream stream = null; CryptoStream stream2 = null; try { Rfc2898DeriveBytes bytes = new Rfc2898DeriveBytes(this.fPassword, this.Salt); managed = new AesManaged(); managed.set_Key(bytes.GetBytes(managed.get_KeySize() / 8)); managed.set_IV(bytes.GetBytes(managed.get_BlockSize() / 8)); stream = new MemoryStream(); stream2 = new CryptoStream(stream, managed.CreateDecryptor(), 1); stream2.Write(data, 0, data.Length); stream2.FlushFinalBlock(); return stream.ToArray(); } catch { return data; } } 通过以下代码无法实现解密 Java code public byte[] dePBE(byte[] data){ try { char[] password = this.fPassword.toCharArray(); byte[] salt = this.fSalt; KeySpec spec = new PBEKeySpec(password,salt,1000,128); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1"); SecretKey tmp = factory.generateSecret(spec); SecretKey secret = new SecretKeySpec(tmp.getEncoded(), "AES"); Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); cipher.init(Cipher.DECRYPT_MODE, secret, new IvParameterSpec(new byte[cipher.getBlockSize()])); byte[] ciphertext = cipher.doFinal(data); return ciphertext; }catch (Exception e) { e.printStackTrace(); return null; } }

java解决方案:

找到一个复刻的Rfc2898DeriveBytes类
http://www.itstrike.cn/Question/fc038543-6a4e-4796-8333-6b1c1b5cce12.html

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 };
    }
 
}
只要这样就可可以解决了

Java code

public byte[] deRfc2898DeriveBytes(byte[] data,String fPassword,byte[] fSalt){
    Rfc2898DeriveBytes keyGenerator = null;
    try {
        keyGenerator = new Rfc2898DeriveBytes(fPassword, fSalt, 1000);
    }
    catch (InvalidKeyException e1) { 
        e1.printStackTrace();
    } catch (NoSuchAlgorithmException e1) {
        e1.printStackTrace();
    } catch (UnsupportedEncodingException e1) {
        e1.printStackTrace();
    } 
    //Log.i("key = ", decodeUTF8(keyGenerator.getBytes(16)));
     
    byte[] bKey = keyGenerator.getBytes(32);
    byte[] bIv = keyGenerator.getBytes(16);
     
    try {
        SecretKeySpec sekey = new SecretKeySpec(bKey, "AES");
        AlgorithmParameterSpec param = new IvParameterSpec(bIv);
         
        Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
        cipher.init(Cipher.DECRYPT_MODE,sekey,param);
        byte[] decrypted = cipher.doFinal(data);
        return decrypted;
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值