Java SSHA 匹配算法

发布于 2021-05-11 19:05:26 字数 3385 浏览 1787 评论 0

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

import sun.misc.BASE64Encoder;
import sun.misc.BASE64Decoder;

public class EncryptUtil {

  public static void main(String[] args) throws IOException {


    String original = "{SSHA}xn/c1xL9cEMeTi+aTIqI0X2ftJ1notFppwCk7A==";
    String password = "123456";

    System.out.println(original);
    boolean isSame = verifyPassword(original, password);

    System.out.println(isSame);
  }

  /**
   * Splits a byte array into two.
   *
   * @param src
   *      byte array to split
   * @param n
   *      location to split the array
   * @return a two dimensional array of the split
   */
  private static byte[][] split(byte[] src, int n) {
    byte[] l;
    byte[] r;

    if (src.length <= n) {
      l = src;
      r = new byte[0];

    } else {
      l = new byte[n];
      r = new byte[src.length - n];
      System.arraycopy(src, 0, l, 0, n);
      System.arraycopy(src, n, r, 0, r.length);
    }

    byte[][] lr = { l, r };

    return lr;

  }

  /**
   * Validates if a plaintext password matches a hashed version.
   *
   * @param digest
   *      digested version
   * @param password
   *      plaintext password
   * @return if the two match
   */
  public static boolean verifyPassword(String digest, String password) {
    String alg = null;
    int size = 0;

    if (digest.regionMatches(true, 0, "{SHA}", 0, 5)) {
      digest = digest.substring(5);
      alg = "SHA1";
      size = 20;

    } else if (digest.regionMatches(true, 0, "{SSHA}", 0, 6)) {
      digest = digest.substring(6);
      alg = "SHA1";
      size = 20;

    } else if (digest.regionMatches(true, 0, "{MD5}", 0, 5)) {
      digest = digest.substring(5);
      alg = "MD5";
      size = 16;

    } else if (digest.regionMatches(true, 0, "{SMD5}", 0, 6)) {
      digest = digest.substring(6);
      alg = "MD5";
      size = 16;

    }

    try {
      MessageDigest mDigest = MessageDigest.getInstance(alg);

      if (mDigest == null) {
        return false;
      }
      BASE64Encoder enc = new BASE64Encoder();
      BASE64Decoder decoder = new BASE64Decoder();

      byte[] decodeBase64 = decoder.decodeBuffer(digest);
      byte[][] hs =split(decodeBase64, size);
      byte[] hash = hs[0];
      byte[] salt = hs[1];
String str_hash = new String(hash);
String str_salt = new String(salt);

System.out.println("hash:");
for(int i=0;i<hash.length;i++)
    System.out.format("%02X",hash[i]);
System.out.println();
System.out.println("salt:");
for(int i=0;i<salt.length;i++)
    System.out.format("%02X",salt[i]);
System.out.println();
      mDigest.reset();
      mDigest.update(password.getBytes());
      mDigest.update(salt);

      byte[] pwhash = mDigest.digest();

      return MessageDigest.isEqual(hash, pwhash);

    } catch (NoSuchAlgorithmException nsae) {
      return false;
    } catch (IOException e) {
      e.printStackTrace();
    }

    return false;
  }
}

SSHA 算法的总结:加密盐 salt 是 8 个字节。密码转换成字节,加上 8 个字节的 salt,然后进行 SHA-1 散列。散列值 base64 后,最前面加上 {SSHA}

解析:去掉 {SSHA} 进行 base64 解码。得到 28 个字节,最后 8 个字节是 salt。前面 20 个字节是 SHA-1 散列值。散列值是密码和 salt 连接后 SHA-1 计算得到的。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84961 人气
更多

推荐作者

醉城メ夜风

文章 0 评论 0

远昼

文章 0 评论 0

平生欢

文章 0 评论 0

微凉

文章 0 评论 0

Honwey

文章 0 评论 0

qq_ikhFfg

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文