Java 常用的 4 種加密方式

蝴蝶飛啊飛發表於2019-10-23

一、工具類

 md5 加密工具類

public class MD5Utils  

    private static final String hexDigIts[] = {"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};

    /**

     * MD5 加密

     * @param origin 字元

     * @param charsetname 編碼

     * @return

     */

    public static String MD5Encode(String origin, String charsetname){

        String resultString = null;

        try{

            resultString = new String(origin);

            MessageDigest md = MessageDigest.getInstance("MD5");

            if(null == charsetname || "".equals(charsetname)){

                resultString = byteArrayToHexString(md.digest(resultString.getBytes()));

            }else{

                resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname)));

            }

        }catch (Exception e){

        }

        return resultString;

    }

    public static String byteArrayToHexString(byte b[]){

        StringBuffer resultSb = new StringBuffer();

        for(int i = 0; i < b.length; i++){

            resultSb.append(byteToHexString(b[i]));

        }

        return resultSb.toString();

    }

    public static String byteToHexString(byte b){

        int n = b;

        if(n < 0){

            n += 256;

        }

        int d1 = n / 16;

        int d2 = n % 16;

        return hexDigIts[d1] + hexDigIts[d2];

    }

}

Java MD5 雜湊示例

public class SimpleMD5Example

{

    public static void main(String[] args)

    {

        String passwordToHash = "password";

        String generatedPassword = null;

        try {

            // Create MessageDigest instance for MD5

            MessageDigest md = MessageDigest.getInstance("MD5");

            //Add password bytes to digest

            md.update(passwordToHash.getBytes());

            //Get the hash's bytes

            byte[] bytes = md.digest();

            //This bytes[] has bytes in decimal format;

            //Convert it to hexadecimal format

            StringBuilder sb = new StringBuilder();

            for(int i=0; i< bytes.length ;i++)

            {

                sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));

            }

            //Get complete hashed password in hex format

           generatedPassword = sb.toString();

        }

        catch (NoSuchAlgorithmException e)

        {

            e.printStackTrace();

       }

        System.out.println(generatedPassword);

    }

}

儘管MD5 是一種廣泛使用的雜湊演算法,但遠非安全, MD5 會產生相當弱的雜湊值。它的主要優點是速度快,易於實施。但這也意味著它容易受到 蠻力和字典攻擊。

生成單詞和雜湊的彩虹表允許非常快速地搜尋已知雜湊並獲得原始單詞。

MD5 不是抗衝突的,這意味著不同的密碼最終會導致相同的雜湊。

今天,如果您在應用程式中使用MD5 雜湊,請考慮在安全性中新增一些鹽。

使用salt 使 MD5 更安全

請記住,新增鹽不是MD5 特定的。您也可以將其新增到其他演算法中。因此,請關注它的應用方式,而不是它與 MD5 的關係。

維基百科將salt 定義為隨機資料,用作雜湊密碼或密碼短語的單向函式的附加輸入。更簡單的說, salt 是一些隨機生成的文字,在獲取雜湊值之前會附加到密碼中。

salting 的最初意圖主要是打敗預先計算的彩虹表攻擊,否則可以用來大大提高資料庫的效率。現在更大的好處是減慢並行操作,將一次密碼猜測的雜湊值與多個密碼雜湊值進行比較。

重要提示:我們總是需要使用SecureRandom 來建立好的鹽,而在 Java 中, SecureRandom 類支援“ SHA1PRNG ”偽隨機數生成器演算法,我們可以利用它。

如何為Hash 生成 Salt

讓我們看看應該如何生成鹽。

private static byte[] getSalt() throws NoSuchAlgorithmException

{

    //Always use a SecureRandom generator

    SecureRandom sr = SecureRandom.getInstance("SHA1PRNG");

    //Create array for salt

    byte[] salt = new byte[16];

    //Get a random salt

    sr.nextBytes(salt);

    //return salt

    return salt;

}

SHA1PRNG 演算法用作基於 SHA-1 訊息摘要演算法的加密強偽隨機數生成器。請注意,如果未提供種子,它將從真正的隨機數生成器( TRNG )生成種子。

Java MD5 與鹽的例子

現在,讓我們看看修改後的MD5 雜湊示例:

public class SaltedMD5Example

{

    public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException

    {

        String passwordToHash = "password";

        byte[] salt = getSalt();

        String securePassword = getSecurePassword(passwordToHash, salt);

        System.out.println(securePassword); //Prints 83ee5baeea20b6c21635e4ea67847f66  

        String regeneratedPassowrdToVerify = getSecurePassword(passwordToHash, salt);

        System.out.println(regeneratedPassowrdToVerify); //Prints 83ee5baeea20b6c21635e4ea67847f66

    }

private static String getSecurePassword(String passwordToHash, byte[] salt)

    {

        String generatedPassword = null;

        try {

            // Create MessageDigest instance for MD5

            MessageDigest md = MessageDigest.getInstance("MD5");

            //Add password bytes to digest

            md.update(salt);

            //Get the hash's bytes

            byte[] bytes = md.digest(passwordToHash.getBytes());

            //This bytes[] has bytes in decimal format;

            //Convert it to hexadecimal format

            StringBuilder sb = new StringBuilder();

            for(int i=0; i< bytes.length ;i++)

            {

                sb.append(Integer.toString((bytes[i] & 0xff) + 0x100, 16).substring(1));

            }

            //Get complete hashed password in hex format

            generatedPassword = sb.toString();

        }

        catch (NoSuchAlgorithmException e) {

           e.printStackTrace();

        }

        return generatedPassword;

    }

    //Add salt

    private static byte[] getSalt() throws NoSuchAlgorithmException, NoSuchProviderException

    {

        //Always use a SecureRandom generator

        SecureRandom sr = SecureRandom.getInstance("SHA1PRNG", "SUN");

        //Create array for salt

        byte[] salt = new byte[16];

        //Get a random salt

        sr.nextBytes(salt);

        //return salt

        return salt;

    }

}

重要提示:請注意,現在您必須為您雜湊的每個密碼儲存此salt 值。因為當使用者在系統中重新登入時,必須僅使用最初生成的 salt 再次建立雜湊以匹配儲存的雜湊。如果使用不同的外匯返傭http://www.kaifx.cn/鹽(我們生成隨機鹽),則生成的雜湊將不同。

此外,您可能聽說過瘋狂雜湊和醃製這個術語。它通常指建立自定義組合。

base64 加密工具類

public class Base64Util {

    // 字串編碼

    private static final String UTF_8 = "UTF-8";

    /**

     * 加密字串

     * @param inputData

     * @return

     */

    public static String decodeData(String inputData) {

        try {

            if (null == inputData) {

                return null;

            }

            return new String(Base64.decodeBase64(inputData.getBytes(UTF_8)), UTF_8);

        } catch (UnsupportedEncodingException e) {

        }

        return null;

    }

    /**

     * 解密加密後的字串

     * @param inputData

     * @return

     */

    public static String encodeData(String inputData) {

        try {

            if (null == inputData) {

                return null;

            }

            return new String(Base64.encodeBase64(inputData.getBytes(UTF_8)), UTF_8);

        } catch (UnsupportedEncodingException e) {

        }

        return null;

    }

    public static void main(String[] args) {

        System.out.println(Base64Util.encodeData(" 我是中文 "));

        String enStr = Base64Util.encodeData(" 我是中文 ");

        System.out.println(Base64Util.decodeData(enStr));

    }

}

 Bcrypt 工具類

public class BcryptCipher {

  // generate salt seed

  private static final int SALT_SEED = 12;

  // the head fo salt

  private static final String SALT_STARTSWITH = "$2a$12";

  public static final String SALT_KEY = "salt";  

  public static final String CIPHER_KEY = "cipher";

  /**

   * Bcrypt encryption algorithm method

   * @param encryptSource

   * need to encrypt the string

   * @return Map , two values in Map , salt and cipher

   */

  public static Map<String, String> Bcrypt(final String encryptSource) {

    String salt = BCrypt.gensalt(SALT_SEED);

    Map<String, String> bcryptResult = Bcrypt(salt, encryptSource);

    return bcryptResult;

  }

  /**

   *

   * @param salt encrypt salt, Must conform to the rules

   * @param encryptSource

   * @return

   */

  public static Map<String, String> Bcrypt(final String salt, final String encryptSource) {

    if (StringUtils.isBlank(encryptSource)) {

      throw new RuntimeException("Bcrypt encrypt input params can not be empty");

    }

    if (StringUtils.isBlank(salt) || salt.length() != 29) {

      throw new RuntimeException("Salt can't be empty and length must be to 29");

    }

    if (!salt.startsWith(SALT_STARTSWITH)) {

      throw new RuntimeException("Invalid salt version, salt version is $2a$12");

    }

    String cipher = BCrypt.hashpw(encryptSource, salt);

    Map<String, String> bcryptResult = new HashMap<String, String>();

    bcryptResult.put(SALT_KEY, salt);

    bcryptResult.put(CIPHER_KEY, cipher);

    return bcryptResult;

  }

}

二、加密測試

MD5 加密測試

/**

 * MD5 加密

 */

public class MD5Test {

  public static void main(String[] args) {

    String string = " 你好 世界 ";

    String byteArrayToHexString = MD5Utils.byteArrayToHexString(string.getBytes());

    System.out.println(byteArrayToHexString);//e68891e698afe4b880e58fa5e8af9d

  }

}

base64 加密測試

/**

 * base64 加密

 */

public class Bast64Tester {

  public static void main(String[] args) {

    String string = " 你好 世界 ";

    String encodeData = Base64Util.encodeData(string); // 加密

    String decodeData = Base64Util.decodeData(encodeData); // 解密

    System.out.println(encodeData);//5oiR5piv5LiA5Liq5a2X56ym5Liy

    System.out.println(decodeData);// 你好 世界

  }

}

SHA 加密測試

/**

 * SHA 加密

 */

public class ShaTest {

  public static void main(String[] args) {

    String string = " 你好 世界 ";

    String sha256Crypt = Sha2Crypt.sha256Crypt(string.getBytes());   System.out.println(sha256Crypt);//$5$AFoQTeyt$TiqmobvcQXjXaAQMYosAAO4KI8LfigZMGHzq.Dlp4NC

  }

}

BCrypt 加密測試

/**

 * BCrypt 加密

 */

public class BCryptTest {

  public static void main(String[] args) {

    String string = " 你好世界 ";

    Map<String, String> bcrypt = BcryptCipher.Bcrypt(string);

    System.out.println(bcrypt.keySet()); //[cipher, salt]

    System.out.println(bcrypt.get("cipher")); //$2a$12$ylb92Z84gqlrSfzIztlCV.dK0xNbw.pOv3UwXXA76llOsNRTJsE/.

    System.out.println(bcrypt.get("salt")); //$2a$12$ylb92Z84gqlrSfzIztlCV.

    Map<String, String> bcrypt2 = BcryptCipher.Bcrypt(bcrypt.get("salt"),string);

    System.out.println(bcrypt2.get("SALT_KEY")); //null

    System.out.println(bcrypt2.get("CIPHER_KEY")); //null

  }

}


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69946279/viewspace-2661081/,如需轉載,請註明出處,否則將追究法律責任。

相關文章