我正在寻找一种加密四位密码的方法,结果得到一个16chars的字符串。
到目前为止,我已经使用此
获得了64个字符串public static String digestHex(String text) {
StringBuilder stringBuffer = new StringBuilder();
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");// SHA-256
digest.reset();
for (byte b : digest.digest(text.getBytes("UTF-8"))) {
stringBuffer.append(Integer.toHexString((int) (b & 0xff)));
}
} catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
e.printStackTrace();
}
return stringBuffer.toString();
}
是text = 1234 生成的字符串是= 3ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4使用Java btw:D
答案 0 :(得分:1)
任何“加密”方案,您在没有额外密钥的情况下加密4位数字实际上是一种查找方案。由于查找方案只有10,000个唯一的“输入”,因此通过尝试所有输入来破解加密将相对容易。
换句话说,加密的PIN码的安全性是一种错觉......除非您在加密输入之前执行类似“播种”输入的操作。
答案 1 :(得分:0)
您使用的是SHA-256。该算法生成32字节长的消息(256位,more details here)。
这就是为什么你获得一个64字节长的十六进制字符串作为输出:Integer.toHexString((int) (b & 0xff))
将b
的每个MessageDigest
字节转换成一个2字节长的十六进制String
表示。
要获得16字节长的字符串,您可以使用MD5(16字节输出,如果以十六进制转换,则为32),派生该字符串或使用完全不同的方式,例如实际使用加密(使用javax.crypto.Cipher
)
我需要知道您希望进一步详细说明,知道使用MessageDigest
实际上是哈希,而不是加密,而在帖子的第一行,您说的是加密。其中一个不同之处在于哈希码不是设计为可逆的,而是进行比较,这与可逆的加密不同。请参阅this interesting SO post。
答案 2 :(得分:0)
你的安全性放在一边 - 有更简单的方法可以做到这一点:
// Your original - with the horrible exception hiding removed.
public static String digestHex(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
StringBuilder stringBuffer = new StringBuilder();
MessageDigest digest = MessageDigest.getInstance("SHA-256");// SHA-256
digest.reset();
for (byte b : digest.digest(text.getBytes("UTF-8"))) {
stringBuffer.append(Integer.toHexString((int) (b & 0xff)));
}
return stringBuffer.toString();
}
// Uses BigInteger.
public static String digest(String text, int base) throws NoSuchAlgorithmException, UnsupportedEncodingException {
MessageDigest digest = MessageDigest.getInstance("SHA-256");// SHA-256
digest.reset();
BigInteger b = new BigInteger(digest.digest(text.getBytes("UTF-8")));
return b.toString(base);
}
public void test() throws NoSuchAlgorithmException, UnsupportedEncodingException {
System.out.println("Hex:" + digestHex("1234"));
System.out.println("Hex:" + digest("1234", 16));
System.out.println("36:" + digest("1234", 36));
System.out.println("Max:" + digest("1234", Character.MAX_RADIX));
}
这允许你在更高的基础上生成字符串 - 从而缩短数字但遗憾的是你仍然没有达到16。
如果您真的存在16个字符,我建议您使用一种简单的CRC算法。或者你可以试试base 62或base 64 - 那里有很多实现。