可变MD5加密(Java实现)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可变MD5加密(Java实现)相关的知识,希望对你有一定的参考价值。

参考技术A

  可变在这里含义很简单 就是最终的加密结果是可变的 而非必需按标准MD 加密实现 Java类库security中的MessageDigest类就提供了MD 加密的支持 实现起来非常方便 为了实现更多效果 我们可以如下设计MD 工具类

  Java代码

  package ** ** util;

  import java security MessageDigest;

  /**

  * 标准MD 加密方法 使用java类库的security包的MessageDigest类处理

  * @author Sarin

  */

  public class MD

  /**

  * 获得MD 加密密码的方法

  */

  public static String getMD ofStr(String origString)

  String origMD = null;

  try

  MessageDigest md = MessageDigest getInstance( MD );

  byte[] result = md digest(origString getBytes());

  origMD = byteArray HexStr(result);

   catch (Exception e)

  e printStackTrace();

  

  return origMD ;

  

  /**

  * 处理字节数组得到MD 密码的方法

  */

  private static String byteArray HexStr(byte[] bs)

  StringBuffer *** = new StringBuffer();

  for (byte b : bs)

   *** append(byte HexStr(b));

  

  return *** toString();

  

  /**

  * 字节标准移位转十六进制方法

  */

  private static String byte HexStr(byte b)

  String hexStr = null;

  int n = b;

  if (n < )

  //若需要自定义加密 请修改这个移位算法即可

  n = b & x F + ;

  

  hexStr = Integer toHexString(n / ) + Integer toHexString(n % );

  return hexStr toUpperCase();

  

  /**

  * 提供一个MD 多次加密方法

  */

  public static String getMD ofStr(String origString int times)

  String md = getMD ofStr(origString);

  for (int i = ; i < times ; i++)

  md = getMD ofStr(md );

  

  return getMD ofStr(md );

  

  /**

  * 密码验证方法

  */

  public static boolean verifyPassword(String inputStr String MD Code)

  return getMD ofStr(inputStr) equals(MD Code);

  

  /**

  * 重载一个多次加密时的密码验证方法

  */

  public static boolean verifyPassword(String inputStr String MD Code int times)

  return getMD ofStr(inputStr times) equals(MD Code);

  

  /**

  * 提供一个测试的主函数

  */

  public static void main(String[] args)

  System out println( : + getMD ofStr( ));

  System out println( : + getMD ofStr( ));

  System out println( sarin: + getMD ofStr( sarin ));

  System out println( : + getMD ofStr( ));

  

  

  可以看出实现的过程非常简单 因为由java类库提供了处理支持 但是要清楚的是这种方式产生的密码不是标准的MD 码 它需要进行移位处理才能得到标准MD 码 这个程序的关键之处也在这了 怎么可变?调整移位算法不就可变了么!不进行移位 也能够得到 位的密码 这就不是标准加密了 只要加密和验证过程使用相同的算法就可以了

  MD 加密还是很安全的 像CMD 那些穷举破解的只是针对标准MD 加密的结果进行的 如果自定义移位算法后 它还有效么?可以说是无解的了 所以MD 非常安全可靠

  为了更可变 还提供了多次加密的方法 可以在MD 基础之上继续MD 就是对 位的第一次加密结果再MD 恩 这样去破解?没有任何意义

  这样在MIS系统中使用 安全可靠 欢迎交流 希望对使用者有用

  我们最后看看由MD 加密算法实现的类 那是非常庞大的

  Java代码

  import java lang reflect *;

  /**

  * **********************************************

  * md 类实现了RSA Data Security Inc 在提交给IETF

  * 的RFC 中的MD message digest 算法

  * ***********************************************

  */

  public class MD

  /* 下面这些S S 实际上是一个 * 的矩阵 在原始的C实现中是用#define 实现的

  这里把它们实现成为static final是表示了只读 切能在同一个进程空间内的多个

  Instance间共享*/

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final int S = ;

  static final byte[] PADDING =

  

   ;

  /* 下面的三个成员是MD 计算过程中用到的 个核心数据 在原始的C实现中

  被定义到MD _CTX结构中

  */

  private long[] state = new long[ ]; // state (ABCD)

  private long[] count = new long[ ]; // number of bits modulo ^ (l *** first)

  private byte[] buffer = new byte[ ]; // input buffer

  /* digestHexStr是MD 的唯一一个公共成员 是最新一次计算结果的

   进制ASCII表示

  */

  public String digestHexStr;

  /* digest 是最新一次计算结果的 进制内部表示 表示 bit的MD 值

  */

  private byte[] digest = new byte[ ];

  /*

  getMD ofStr是类MD 最主要的公共方法 入口参数是你想要进行MD 变换的字符串

  返回的是变换完的结果 这个结果是从公共成员digestHexStr取得的.

  */

  public String getMD ofStr(String inbuf)

  md Init();

  md Update(inbuf getBytes() inbuf length());

  md Final();

  digestHexStr = ;

  for (int i = ; i < ; i++)

  digestHexStr += byteHEX(digest[i]);

  

  return digestHexStr;

  

  // 这是MD 这个类的标准构造函数 JavaBean要求有一个public的并且没有参数的构造函数

  public MD ()

  md Init();

  return;

  

  /* md Init是一个初始化函数 初始化核心变量 装入标准的幻数 */

  private void md Init()

  count[ ] = L;

  count[ ] = L;

  ///* Load magic initialization constants

  state[ ] = x L;

  state[ ] = xefcdab L;

  state[ ] = x badcfeL;

  state[ ] = x L;

  return;

  

  /* F G H I 是 个基本的MD 函数 在原始的MD 的C实现中 由于它们是

  简单的位运算 可能出于效率的考虑把它们实现成了宏 在java中 我们把它们

  实现成了private方法 名字保持了原来C中的 */

  private long F(long x long y long z)

  return (x & y) | ((~x) & z);

  

  private long G(long x long y long z)

  return (x & z) | (y & (~z));

  

  private long H(long x long y long z)

  return x ^ y ^ z;

  

  private long I(long x long y long z)

  return y ^ (x | (~z));

  

  /*

  FF GG HH和II将调用F G H I进行近一步变换

  FF GG HH and II transformations for rounds and

  Rotation is separate from addition to prevent reputation

  */

  private long FF(long a long b long c long d long x long s long ac)

  a += F(b c d) + x + ac;

  a = ((int) a << s) | ((int) a >>> ( s));

  a += b;

  return a;

  

  private long GG(long a long b long c long d long x long s long ac)

  a += G(b c d) + x + ac;

  a = ((int) a << s) | ((int) a >>> ( s));

  a += b;

  return a;

  

  private long HH(long a long b long c long d long x long s long ac)

  a += H(b c d) + x + ac;

  a = ((int) a << s) | ((int) a >>> ( s));

  a += b;

  return a;

  

  private long II(long a long b long c long d long x long s long ac)

  a += I(b c d) + x + ac;

  a = ((int) a << s) | ((int) a >>> ( s));

  a += b;

  return a;

  

  /*

  md Update是MD 的主计算过程 inbuf是要变换的字节串 inputlen是长度 这个

  函数由getMD ofStr调用 调用之前需要调用md init 因此把它设计成private的

  */

  private void md Update(byte[] inbuf int inputLen)

  int i index partLen;

  byte[] block = new byte[ ];

  index = (int) (count[ ] >>> ) & x F;

  // /* Update number of bits */

  if ((count[ ] += (inputLen << )) < (inputLen << ))

  count[ ]++;

  count[ ] += (inputLen >>> );

  partLen = index;

  // Transform as many times as possible

  if (inputLen >= partLen)

  md Memcpy(buffer inbuf index partLen);

  md Transform(buffer);

  for (i = partLen; i + < inputLen; i += )

  md Memcpy(block inbuf i );

  md Transform(block);

  

  index = ;

   else

  i = ;

  ///* Buffer remaining input */

  md Memcpy(buffer inbuf index i inputLen i);

  

  /*

  md Final整理和填写输出结果

  */

  private void md Final()

  byte[] bits = new byte[ ];

  int index padLen;

  ///* Save number of bits */

  Encode(bits count );

  ///* Pad out to mod

  index = (int) (count[ ] >>> ) & x f;

  padLen = (index < ) ? ( index) : ( index);

  md Update(PADDING padLen);

  ///* Append length (before padding) */

  md Update(bits );

  ///* Store state in digest */

  Encode(digest state );

  

  /* md Memcpy是一个内部使用的byte数组的块拷贝函数 从input的inpos开始把len长度的

  字节拷贝到output的outpos位置开始

  */

  private void md Memcpy(byte[] output byte[] input int outpos int inpos int len)

  int i;

  for (i = ; i < len; i++)

  output[outpos + i] = input[inpos + i];

  

  /*

  md Transform是MD 核心变换程序 有md Update调用 block是分块的原始字节

  */

  private void md Transform(byte block[])

  long a = state[ ] b = state[ ] c = state[ ] d = state[ ];

  long[] x = new long[ ];

  Decode(x block );

  /* Round */

  a = FF(a b c d x[ ] S xd aa L); /* */

  d = FF(d a b c x[ ] S xe c b L); /* */

  c = FF(c d a b x[ ] S x dbL); /* */

  b = FF(b c d a x[ ] S xc bdceeeL); /* */

  a = FF(a b c d x[ ] S xf c fafL); /* */

  d = FF(d a b c x[ ] S x c aL); /* */

  c = FF(c d a b x[ ] S xa L); /* */

  b = FF(b c d a x[ ] S xfd L); /* */

  a = FF(a b c d x[ ] S x d L); /* */

  d = FF(d a b c x[ ] S x b f afL); /* */

  c = FF(c d a b x[ ] S xffff bb L); /* */

  b = FF(b c d a x[ ] S x cd beL); /* */

  a = FF(a b c d x[ ] S x b L); /* */

  d = FF(d a b c x[ ] S xfd L); /* */

  c = FF(c d a b x[ ] S xa eL); /* */

  b = FF(b c d a x[ ] S x b L); /* */

  /* Round */

  a = GG(a b c d x[ ] S xf e L); /* */

  d = GG(d a b c x[ ] S xc b L); /* */

  c = GG(c d a b x[ ] S x e a L); /* */

  b = GG(b c d a x[ ] S xe b c aaL); /* */

  a = GG(a b c d x[ ] S xd f dL); /* */

  d = GG(d a b c x[ ] S x L); /* */

  c = GG(c d a b x[ ] S xd a e L); /* */

  b = GG(b c d a x[ ] S xe d fbc L); /* */

  a = GG(a b c d x[ ] S x e cde L); /* */

  d = GG(d a b c x[ ] S xc d L); /* */

  c = GG(c d a b x[ ] S xf d d L); /* */

  b = GG(b c d a x[ ] S x a edL); /* */

  a = GG(a b c d x[ ] S xa e e L); /* */

  d = GG(d a b c x[ ] S xfcefa f L); /* */

  c = GG(c d a b x[ ] S x f d L); /* */

  b = GG(b c d a x[ ] S x d a c aL); /* */

  /* Round */

  a = HH(a b c d x[ ] S xfffa L); /* */

  d = HH(d a b c x[ ] S x f L); /* */

  c = HH(c d a b x[ ] S x d d L); /* */

  b = HH(b c d a x[ ] S xfde cL); /* */

  a = HH(a b c d x[ ] S xa beea L); /* */

  d = HH(d a b c x[ ] S x bdecfa L); /* */

  c = HH(c d a b x[ ] S xf bb b L); /* */

  b = HH(b c d a x[ ] S xbebfbc L); /* */

  a = HH(a b c d x[ ] S x b ec L); /* */

  d = HH(d a b c x[ ] S xeaa faL); /* */

  c = HH(c d a b x[ ] S xd ef L); /* */

  b = HH(b c d a x[ ] S x d L); /* */

  a = HH(a b c d x[ ] S xd d d L); /* */

  d = HH(d a b c x[ ] S xe db e L); /* */

  c = HH(c d a b x[ ] S x fa cf L); /* */

  b = HH(b c d a x[ ] S xc ac L); /* */

  /* Round */

  a = II(a b c d x[ ] S xf L); /* */

  d = II(d a b c x[ ] S x aff L); /* */

  c = II(c d a b x[ ] S xab a L); /* */

  b = II(b c d a x[ ] S xfc a L); /* */

  a = II(a b c d x[ ] S x b c L); /* */

  d = II(d a b c x[ ] S x f ccc L); /* */

  c = II(c d a b x[ ] S xffeff dL); /* */

  b = II(b c d a x[ ] S x dd L); /* */

  a = II(a b c d x[ ] S x fa e fL); /* */

  d = II(d a b c x[ ] S xfe ce e L); /* */

  c = II(c d a b x[ ] S xa L); /* */

  b = II(b c d a x[ ] S x e a L); /* */

  a = II(a b c d x[ ] S xf e L); /* */

  d = II(d a b c x[ ] S xbd af L); /* */

  c = II(c d a b x[ ] S x ad d bbL); /* */

  b = II(b c d a x[ ] S xeb d L); /* */

  state[ ] += a;

  state[ ] += b;

  state[ ] += c;

  state[ ] += d;

  

  /*Encode把long数组按顺序拆成byte数组 因为java的long类型是 bit的

  只拆低 bit 以适应原始C实现的用途

  */

  private void Encode(byte[] output long[] input int len)

  int i j;

  for (i = j = ; j < len; i++ j += )

  output[j] = (byte) (input[i] & xffL);

  output[j + ] = (byte) ((input[i] >>> ) & xffL);

  output[j + ] = (byte) ((input[i] >>> ) & xffL);

  output[j + ] = (byte) ((input[i] >>> ) & xffL);

  

  

  /*Decode把byte数组按顺序合成成long数组 因为java的long类型是 bit的

  只合成低 bit 高 bit清零 以适应原始C实现的用途

  */

  private void Decode(long[] output byte[] input int len)

  int i j;

  for (i = j = ; j < len; i++ j += )

  output[i] = b iu(input[j]) | (b iu(input[j + ]) << ) | (b iu(input[j + ]) << )

  | (b iu(input[j + ]) << );

  return;

  

  /*

  b iu是我写的一个把byte按照不考虑正负号的原则的"升位"程序 因为java没有unsigned运算

  */

  public static long b iu(byte b)

  return b < ? b & x F + : b;

  

  /*byteHEX() 用来把一个byte类型的数转换成十六进制的ASCII表示

  因为java中的byte的toString无法实现这一点 我们又没有C语言中的

  sprintf(outbuf % X ib)

  */

  public static String byteHEX(byte ib)

  char[] Digit = A B C D E F ;

  char[] ob = new char[ ];

  ob[ ] = Digit[(ib >>> ) & X F];

  ob[ ] = Digit[ib & X F];

  String s = new String(ob);

  return s;

  

  public static void main(String args[])

  MD m = new MD ();

  if (Array getLength(args) == ) //如果没有参数 执行标准的Test Suite

  System out println( MD Test suite: );

  System out println( MD (\\ \\ ): + m getMD ofStr( ));

  System out println( MD (\\ a\\ ): + m getMD ofStr( a ));

  System out println( MD (\\ abc\\ ): + m getMD ofStr( abc ));

  System out println( MD (\\ \\ ): + m getMD ofStr( ));

  System out println( MD (\\ \\ ): + m getMD ofStr( ));

  System out println( MD (\\ message digest\\ ): + m getMD ofStr( message digest ));

  System out println( MD (\\ abcdefghijklmnopqrstuvwxyz\\ ): + m getMD ofStr( abcdefghijklmnopqrstuvwxyz ));

  System out println( MD (\\ ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz \\ ):

  + m getMD ofStr( ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ));

   else

  System out println( MD ( + args[ ] + )= + m getMD ofStr(args[ ]));

  

lishixinzhi/Article/program/Java/hx/201311/26604

Java 语言实现 MD5 加密

Java 语言实现 MD5 加密


 

背景说明

在实际项目中,为了安全性考虑,经常要求账号密码是以加密后的密文形式保存到数据库中

这样,即使有人获取到了数据库中的密文密码,也不知道明文密码信息是什么,从而防止系统被恶意访问。

密码加密有很多种方式,比如:Base64DSARSAMD5SHA128SHA256SHA512等加密方式。

本文主要讲述 MD5 加密方式。


 

MD5 简介

MD5 消息摘要算法(英文:MD5 Message-Digest Algorithm),一种被广泛使用的密码散列函数,可以产生出一个128位(16字节)的散列值(hash value),用于确保信息传输完整一致。

MD5由美国密码学家罗纳德·李维斯特(Ronald Linn Rivest)设计,于1992年公开,用以取代MD4算法。


 

 MD5应用

1、数据加密

利用它的单向加密性,即不可逆性,我们可以应用于数据和密码的加密

由于MD5算法的单向性,由MD5码计算出原文几乎是不可能的。目前对于这种加密方法的破解方式是收集常用的密码形式,例如生日,身份证号,电话号码等。把这些收集到的秘密用MD5处理之后进行存储,然后与需要还原的MD5进行比对,当收集的数据达到一定的数目,用户密码被破解的可能性就会变得很大。

对于这种方法,一种加强安全性的方法就是在对用户密码进行MD5处理的时候在原密码上加一个附近值,例如原密码为“password”,处理的时候变为“passworddrowssap”,经过这样的处理之后可以有效降低密码被破解的可能性。

 

2、确认文件是否被篡改

每个文件都可以计算出一个特定MD5 值

比如,我们上传一个文件到服务器上,可以同时计算出该文件对应的 MD5 值;

在文件下载的时候,通过再次计算该文件的 MD5 值。

如果两个MD5值相同,说明文件没有变化,否则,说明文件被修改过。


 

Java 语言实现 MD5 加密

通过Java编写程序,实现对任意字符串进行 MD5 加密。

1、第一版代码(初始版

代码如下:

package com.miracle.luna.md5;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by Miracle Luna on 2019/11/18
 */
public class Md5UtilOriginal {

    /**
     * 将数据进行 MD5 加密,并以16进制字符串格式输出
     * @param data
     * @return
     */
    public static String md5(String data) {
        try {
            byte[] md5 = md5(data.getBytes("utf-8"));
            return toHexString(md5);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 将字节数组进行 MD5 加密
     * @param data
     * @return
     */
    public static byte[] md5(byte[] data) {
        try {
            MessageDigest md = MessageDigest.getInstance("md5");
            return md.digest(data);
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return new byte[]{};
    }

    /**
     * 将加密后的字节数组,转换成16进制的字符串
     * @param md5
     * @return
     */
    private static String toHexString(byte[] md5) {
        StringBuilder sb = new StringBuilder();
        System.out.println("md5.length: " + md5.length);
        for (byte b : md5) {
            sb.append(Integer.toHexString(b & 0xff));
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        String password = "password";
        String md5HexStr = md5(password);
        System.out.println("==> MD5 加密前: " + password);
        System.out.println("==> MD5 加密后: " + md5HexStr);
    }
}

 

运行结果如下:

md5.length: 16
==> MD5 加密前: password
==> MD5 加密后: 5f4dcc3b5aa765d61d8327deb882cf99

 

2、第二版代码(精简版

代码如下:

package com.miracle.luna.md5;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by Miracle Luna on 2019/11/18
 */
public class Md5UtilSimple {

    /**
     * 将数据进行 MD5 加密,并以16进制字符串格式输出
     * @param data
     * @return
     */
    public static String md5(String data) {
        StringBuilder sb = new StringBuilder();
        try {
            MessageDigest md = MessageDigest.getInstance("md5");
            byte[] md5 = md.digest(data.getBytes(StandardCharsets.UTF_8));

            // 将字节数据转换为十六进制
            for (byte b : md5) {
                sb.append(Integer.toHexString(b & 0xff));
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    public static void main(String[] args) {
        String password = "password";
        String md5HexStr = md5(password);
        System.out.println("==> MD5 加密前: " + password);
        System.out.println("==> MD5 加密后: " + md5HexStr);
    }
}

 

运行结果如下:

==> MD5 加密前: password
==> MD5 加密后: 5f4dcc3b5aa765d61d8327deb882cf99

 

3、第三版代码(最终优化版

代码如下:

package com.miracle.luna.md5;

// 此处需要引入 commons-codec-1.13.jar
import org.apache.commons.codec.binary.Hex;

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by Miracle Luna on 2019/11/18
 */
public class Md5Util {

    /**
     * 将数据进行 MD5 加密,并以16进制字符串格式输出
     * @param data
     * @return
     */
    public static String md5(String data) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            return Hex.encodeHexString(md.digest(data.getBytes(StandardCharsets.UTF_8)));
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return "";
    }

    public static void main(String[] args) {
        String password = "password";
        String md5HexStr = md5(password);
        System.out.println("==> MD5 加密前: " + password);
        System.out.println("==> MD5 加密后: " + md5HexStr);
    }
}

 

运行结果如下:

==> MD5 加密前: password
==> MD5 加密后: 5f4dcc3b5aa765d61d8327deb882cf99

commons-codec-1.13.jarpom 引用如下:
<!-- https://mvnrepository.com/artifact/commons-codec/commons-codec -->
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.13</version>
        </dependency> 



MD5 在线加密&解密工具

1、MD5 在线加密工具

http://www.bejson.com/enc/md5/ (不仅支持 MD5加密,还支持 Base64,SHA等)

效果如下(在“加密前”后的输入框中输入需要 MD5 加密的字符串 --> 点击“MD5加密” --> 即可在“加密后”的显示显示框中看到加密后的密文):

 

2、MD5 在线解密

1) https://www.somd5.com/

效果如下(输入框中输入需要解密的 MD5 密文,点击解密即可解密 ):

 

2) https://www.cmd5.com/ (这是一款很强大的解密工具,不仅支持 MD5,还支持SHA的解密)

效果如下(在密文输入框中输入 MD5 密文,点击“解密”,即可看到 MD5 的明文):

 

解密种类众多,选择范围如下:


 

MD5 密码安全性优化

由于现在直接将密码用 MD5 算法加密存在一定的安全隐患(被暴力破解的可能性),我们可以根据实际的需要,对密码加密的过程做一些逻辑处理。

比如,如下逻辑处理:

1)password --> Base64 加密,得到加密后的密码A;

2)password --> 翻转得到drowssap --> MD5 加密,得到加密后的密码B;

3)密码A+密码B拼接 --> MD5 加密,得到加密后的密码C;

4)密码C --> 翻转操作,产生密码D,作为最终的密文密码存到数据库中。

这样可以增强密码的安全性,减少被破解的可能性。(此处具体的逻辑优化,可以根据个人喜好和实际需求,灵活定义其变换的复杂性)。  


 

【额外补充】 

当密码以 MD5 密文存入到数据库中,用户登录的时候,前端将用户输入的明文密码传输给后端。

后端程序用同样的处理逻辑对其进行 MD5 加密,用加密后的密码与数据库中该用户的密文密码比较。

如果二者相等,说明用户输入的密码正确,允许访问系统;否则,说明密码不正确,禁止访问。

 

另外,为了系统的安全性考虑防止恶意暴力尝试破解密码,我们经常限制用户输入密码错误次数

比如,连续输入3次或者5次密码,将会自动锁定账号一段时间(根据实际场景,设置锁定时长)。

 

关于 Base64 加密&解密 的Java 语言实现,请参考博客:https://www.cnblogs.com/miracle-luna/p/11128734.html

 

希望能帮到大家,谢谢!

以上是关于可变MD5加密(Java实现)的主要内容,如果未能解决你的问题,请参考以下文章

java加密算法实现

Java实现MD5加密及解密的代码实例分享

MD5加密的Java实现

Java 实现32位MD5加密

md5 32位 加密原理 Java实现md5加密

MD5加密算法的Java实现