求java高手帮忙翻译这个段C#的AES算法

 public static class AesSecret
    {
        #region 秘钥对

        private const string saltString = "Wolfy@home";
        private const string pWDString = "home@Wolfy";

        #endregion

        #region 加/解密算法

        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="sSource">需要解密的内容</param>
        /// <returns></returns>
        public static byte[] DecryptString(string strSource)
        {
            byte[] encryptBytes = Convert.FromBase64String(strSource);
            byte[] salt = Encoding.UTF8.GetBytes(saltString);
            //提供高级加密标准 (AES) 对称算法的托管实现。
            AesManaged aes = new AesManaged();
            //通过使用基于 System.Security.Cryptography.HMACSHA1 的伪随机数生成器,实现基于密码的密钥派生功能 (PBKDF2)。
            Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(pWDString, salt);
            // 获取或设置加密操作的块大小(以位为单位)。
            aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
            //获取或设置用于对称算法的密钥大小(以位为单位)。
            aes.KeySize = aes.LegalKeySizes[0].MaxSize;
            //获取或设置用于对称算法的密钥。
            aes.Key = rfc.GetBytes(aes.KeySize / 8);
            //获取或设置用于对称算法的初始化向量 (IV)。
            aes.IV = rfc.GetBytes(aes.BlockSize / 8);

            // 用当前的 Key 属性和初始化向量 IV 创建对称解密器对象
            System.Security.Cryptography.ICryptoTransform decryptTransform = aes.CreateDecryptor();

            // 解密后的输出流
            MemoryStream decryptStream = new MemoryStream();

            // 将解密后的目标流(decryptStream)与解密转换(decryptTransform)相连接
            CryptoStream decryptor = new CryptoStream(
                decryptStream, decryptTransform, CryptoStreamMode.Write);

            // 将一个字节序列写入当前 CryptoStream (完成解密的过程)
            decryptor.Write(encryptBytes, 0, encryptBytes.Length);
            decryptor.Close();

            // 将解密后所得到的流转换为字符串
            return decryptStream.ToArray();

        }

        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="sSource">需要加密的内容</param>
        /// <returns></returns>
        public static byte[] EncryptString(string strSource)
        {
            byte[] data = UTF8Encoding.UTF8.GetBytes(strSource);
            byte[] salt = UTF8Encoding.UTF8.GetBytes(saltString);

            // AesManaged - 高级加密标准(AES) 对称算法的管理类
            AesManaged aes = new AesManaged();

            // Rfc2898DeriveBytes - 通过使用基于 HMACSHA1 的伪随机数生成器,实现基于密码的密钥派生功能 (PBKDF2 - 一种基于密码的密钥派生函数)
            // 通过 密码 和 salt 派生密钥
            Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(pWDString, salt);

            /*
            * AesManaged.BlockSize - 加密操作的块大小(单位:bit)
            * AesManaged.LegalBlockSizes - 对称算法支持的块大小(单位:bit)
            * AesManaged.KeySize - 对称算法的密钥大小(单位:bit)
            * AesManaged.LegalKeySizes - 对称算法支持的密钥大小(单位:bit)
            * AesManaged.Key - 对称算法的密钥
            * AesManaged.IV - 对称算法的密钥大小
            * Rfc2898DeriveBytes.GetBytes(int 需要生成的伪随机密钥字节数) - 生成密钥
            */

            aes.BlockSize = aes.LegalBlockSizes[0].MaxSize;
            aes.KeySize = aes.LegalKeySizes[0].MaxSize;
            aes.Key = rfc.GetBytes(aes.KeySize / 8);
            aes.IV = rfc.GetBytes(aes.BlockSize / 8);

            // 用当前的 Key 属性和初始化向量 IV 创建对称加密器对象
            ICryptoTransform encryptTransform = aes.CreateEncryptor();

            // 加密后的输出流
            MemoryStream encryptStream = new MemoryStream();

            // 将加密后的目标流(encryptStream)与加密转换(encryptTransform)相连接
            CryptoStream encryptor = new CryptoStream
                (encryptStream, encryptTransform, CryptoStreamMode.Write);

            // 将一个字节序列写入当前 CryptoStream (完成加密的过程)
            encryptor.Write(data, 0, data.Length);
            encryptor.Close();

            return encryptStream.ToArray();
        }

        #endregion
    }

我想把这个翻译成java版,水平不够希望大神帮忙一下,这里我万分感谢!

阅读 3.8k
1 个回答

以下为代码:
Rfc2898DeriveBytes.java

package cn.lonecloud.aes;

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 };
    }
 
}

AesSecret.java

package cn.lonecloud.aes;

import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

import org.apache.commons.codec.binary.Base64;
/**
 * AES+PBKDF2 加密
 * @author lonecloud
 *
 */
public class AesSecret {

    // region 秘钥对

    private static final String saltString = "Wolfy@home";
    private static final String pWDString = "home@Wolfy";

    /**
     * 解密
     * @param strSource
     * @return
     */
    public static byte[] DecryptString(String strSource) {
        byte[] result = null;
        try {
            byte[] encryptBytes = Base64.decodeBase64(strSource.getBytes("UTF-8"));
            byte[] salt = saltString.getBytes();
            // 提供高级加密标准 (AES) 对称算法的托管实现。
            KeyGenerator aes = KeyGenerator.getInstance("AES");
            // 通过使用基于 System.Security.Cryptography.HMACSHA1
            // 的伪随机数生成器,实现基于密码的密钥派生功能
            // (PBKDF2)。
            Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(pWDString, salt);
            // 获取或设置用于对称算法的密钥。
            aes.init(128, new SecureRandom(rfc.getBytes(128 / 8)));
            // 获取或设置用于对称算法的初始化向量 (IV)。
            SecretKey key = aes.generateKey();
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, key, new IvParameterSpec((rfc.getBytes(128 / 8))));
            result = cipher.doFinal(encryptBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 将解密后所得到的流转换为字符串
        return result;

    }
    /**
     * 加密
     * @param strSource
     * @return
     */
    public static byte[] EncryptString(String strSource) {
        byte[] result = null;
        try {
            byte[] encryptBytes = strSource.getBytes("UTF-8");
            byte[] salt = saltString.getBytes();
            // 提供高级加密标准 (AES) 对称算法的托管实现。
            // 1.构造密钥生成器,指定为AES算法,不区分大小写
            KeyGenerator aes = KeyGenerator.getInstance("AES");
            // 通过使用基于 System.Security.Cryptography.HMACSHA1
            // 的伪随机数生成器,实现基于密码的密钥派生功能
            // (PBKDF2)。
            Rfc2898DeriveBytes rfc = new Rfc2898DeriveBytes(pWDString, salt);
            // 获取或设置用于对称算法的密钥。
            aes.init(128, new SecureRandom(rfc.getBytes(128 / 8)));
            // 获取或设置用于对称算法的初始化向量 (IV)。
            SecretKey key = aes.generateKey();
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key, new IvParameterSpec((rfc.getBytes(128 / 8))));
            result = cipher.doFinal(encryptBytes);
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 将加密后所得到的流转换为字符串
        return result;
    }
}

测试类

package cn.lonecloud.aes;

import java.io.UnsupportedEncodingException;

import org.apache.commons.codec.binary.Base64;
import org.junit.Test;
/**
 * 测试类
 * @author lonecloud
 *
 */
public class AesTest {

    @Test
    public void aes() throws UnsupportedEncodingException {
        String content = "";
        System.out.println("加密前算法");
        byte[] encryptString = AesSecret.EncryptString(content);
        System.out.println("加密后字符" + byteToHexString(encryptString));
        byte[] encodeBase64 = Base64.encodeBase64(encryptString);
        System.out.println("Base64加密后字符" + byteToHexString(encodeBase64));
        byte[] decryptString = AesSecret.DecryptString(new String(encodeBase64, "UTf-8"));
        System.out.println("解密后的字符串"+new String(decryptString, "UTf-8"));
    }

    public static String byteToHexString(byte[] bytes) {
        StringBuffer sb = new StringBuffer(bytes.length);
        String sTemp;
        for (int i = 0; i < bytes.length; i++) {
            sTemp = Integer.toHexString(0xFF & bytes[i]);
            if (sTemp.length() < 2)
                sb.append(0);
            sb.append(sTemp.toUpperCase());
        }
        return sb.toString();
    }
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题