|
發表者 |
討論內容 |
冷日 (冷日) |
發表時間:2019/5/27 6:13 |
- Webmaster

- 註冊日: 2008/2/19
- 來自:
- 發表數: 15773
|
- [轉貼]Java 的 MD5 加密
Java 的 MD5 加密 現在公司上上下下在瘋資安, 所有的資訊系統都要進行管控, 以往登入比對都是用明碼 (趕時間上線, 能用就行), 管理員都知道每一個人的密碼, 為了怕瓜田李下, 我都要人家隨便用 123 就好, 反正內部網路, 也不怕外部入侵. 但資安來了就不能便宜行事, 所以登入密碼都要加密. 最常用的加密系統是 md5, 例如 PHP 就提供了 md5() 函式, 非常方便. # http://www.w3school.com.cn/php/func_string_md5.asp那 Java 該怎麼做呢? 這要用到 java.security.MessageDigest 這個抽象類別, 呼叫其 getInstance() 並傳入 "MD5" 字串指定其加密演算法就會傳回一個實作此演算法的 MessageDigest 物件, 呼叫此物件的 digest() 方法, 並將欲加密的字串以 byte 陣列方式傳入, 就會傳回以 MD5 加密之 byte 陣列. 其 API 見 : # http://docs.oracle.com/javase/7/docs/api/java/security/MessageDigest.html以下範例是我參考 "Java 程式開發 349 例" 一書中的例子改寫的, import java.security.MessageDigest; public class mytest { public static void main(String[] args) { String str="I love you"; System.out.println( md5(str)); //輸出 E4F58A805A6E1FD0F6BEF58C86F9CEB3 } public static String md5(String str) { String md5=null; try { MessageDigest md= MessageDigest.getInstance("MD5"); byte[] barr= md.digest( str.getBytes()); //將 byte 陣列加密 StringBuffer sb=new StringBuffer(); //將 byte 陣列轉成 16 進制 for (int i=0; i < barr.length; i++) {sb.append( byte2Hex(barr[i]));} String hex=sb.toString(); md5=hex.toUpperCase(); //一律轉成大寫 } catch(Exception e) {e.printStackTrace();} return md5; } public static String byte2Hex
(byte b) { String[] h={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"}; int i=b; if (i < 0) {i += 256;} return h[i/16] + h[i%16]; } } 這裡的 byte2Hex() 方法是用來將經過 md5 加密的每一個 byte 轉成 16 進位表示, 所以 "I love you" 經加密運算後會變成 "E4F58A805A6E1FD0F6BEF58C86F9CEB3". 依據 Wiki 的 MD5 說明, MD5 是一種雜湊演算法, 它會固定生成 32 位的 16 進制數字 (即 128 位元). 即使原文只變動一點點, 演算出來的值卻變動相當大. 例如我們在上面例子中加個驚嘆號 "I love you!", 其 MD5 演算結果變成 "690A8CDA8894E37A6FFF4D1790D53B33", 幾乎完全不一樣了. 最重要的特性是, MD5 是不可逆的, 也就是沒辦法從 "E4F58A805A6E1FD0F6BEF58C86F9CEB3" 反推算出 "I love you", 除非利用超級電腦, 但那也需要很久的時間, 所以只能把它的對應關係記下來. 我在網路上找到下面這個號稱能反解譯的網站, 大約 5 秒就說解出 "I love you" 了, 但要看結果要給錢, 哇咧. # md5在线查询破解,md5解密加密 據說 MD5 在 2009 年被破解了, 在一般電腦只需幾秒鐘, 搞不好這網站是利用這種破解法來做生意的. 原文出處: 小狐狸事務所: Java 的 MD5 加密
|
|
|
冷日 (冷日) |
發表時間:2019/5/27 6:16 |
- Webmaster

- 註冊日: 2008/2/19
- 來自:
- 發表數: 15773
|
- [轉貼]Java 三行代码搞定 MD5 加密
Java三行代码搞定MD5加密Get MD5 Hash In A Few Lines Of Java /** * 對字符串md5加密 * * @param str * @return */ public String getMD5(String str) { String ret = null; try { // 生成一個MD5加密計算摘要 MessageDigest md = MessageDigest.getInstance("MD5"); // 計算md5函數 md.update(str.getBytes()); // digest()最後確定返回md5 hash值,返回值為8為字符串。因為md5 hash值是16位的hex值,實際上就是8位的字符 // BigInteger函數則將8位的字符串轉換成16位hex值,用字符串來表示;得到字符串形式的hash值 ret = new BigInteger(1, md.digest()).toString(16); } catch (Exception e) { //throw new SpeedException("MD5加密出現錯誤"); e.printStackTrace(); } return ret; }
java.math.BigInteger.toString(int radix)方法實例 java.math.BigInteger.toString(int radix) 返回此BigInteger在給定的基數的字符串表示形式。如果基數是從Character.MIN_RADIX到Character.MAX_RADIX包容的範圍內,它會默認為10(因為Integer.toString的情況下)。 聲明 以下是java.math.BigInteger.toString()方法的聲明 public String toString(int radix) 參數 radix – 該字符串表示形式的基數 返回值 此方法返回此BigInteger在給定的基數的字符串表示形式。
BigInteger(byte[] val) BigInteger的大小为val的顺序拼接结果 byte[] val = new byte[]{0x11,0x22,0x33}; BigInteger bigInteger = new BigInteger(val); System.out.println(bigInteger.toString(16)); //16进制输出 , 结果 : 112233
BigInteger(String val, int radix) 得到大小为val , 以 radix 为基数的 BigInteger System.out.println(bigInteger.toString(16));//输出结果 1f System.out.println(bigInteger.toString(10));//输出结果 31
BigInteger b = new BigInteger(s1,16); // 16进制转成大数类型 String s2 = b.toString(16); // 大数类型转成16进制 上列的範例輸入結果: s1: 126656864e144ad88d7ff96badd2f68b s2: 126656864e144ad88d7ff96badd2f68b 如果前2碼修改為00,則: s1: 006656864e144ad88d7ff96badd2f68b s2: 6656864e144ad88d7ff96badd2f68b 所以,最上面的例子,前面要補滿0 才不會出錯。 原文出處: Java三行代码搞定MD5加密 – Max的程式語言筆記
|
|
|
冷日 (冷日) |
發表時間:2019/5/27 6:19 |
- Webmaster

- 註冊日: 2008/2/19
- 來自:
- 發表數: 15773
|
- [轉貼]【Java】MD5 加密
【Java】MD5 加密 參考資料 ---- Android - how to encrypt a string? public String md5(String s) { try { // Create MD5 Hash MessageDigest digest = java.security.MessageDigest.getInstance("MD5"); digest.update(s.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); for(int i=0; i<messageDigest.length; i++) { hexString.append(Integer.toHexString(0xFF & messageDigest[i])); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; }
原文出處:老灰鴨的筆記本: 【Java】MD5 加密
|
|
冷日 (冷日) |
發表時間:2019/5/27 6:25 |
- Webmaster

- 註冊日: 2008/2/19
- 來自:
- 發表數: 15773
|
- [轉貼]How to hash a string in Android?
- How to hash a string in Android?
I am working on an Android app and have a couple strings that I would like to encrypt before sending to a database. I'd like something that's secure, easy to implement, will generate the same thing every time it's passed the same data, and preferably will result in a string that stays a constant length no matter how large the string being passed to it is. Maybe I'm looking for a hash.
This snippet calculate md5 for any given string
public String md5(String s) {
try {
// Create MD5 Hash
MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
digest.update(s.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
for (int i=0; i<messageDigest.length; i++)
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
Source: http://www.androidsnippets.com/snippets/52/index.html
Hope this is useful for you
That function above from (http://www.androidsnippets.org/snippets/52/index.html) is flawed. If one of the digits in the messageDigest is not a two character hex value (i.e. 0x09), it doesn't work properly because it doesn't pad with a 0. If you search around you'll find that function and complaints about it not working. Here a better one found in the comment section of this page, which I slightly modified:
public static String md5(String s)
{
MessageDigest digest;
try
{
digest = MessageDigest.getInstance("MD5");
digest.update(s.getBytes(Charset.forName("US-ASCII")),0,s.length());
byte[] magnitude = digest.digest();
BigInteger bi = new BigInteger(1, magnitude);
String hash = String.format("%0" + (magnitude.length << 1) + "x", bi);
return hash;
}
catch (NoSuchAlgorithmException e)
{
e.printStackTrace();
}
return "";
}
not working method:
public static String md5(String s) {
try {
// Create MD5 Hash
MessageDigest digest = java.security.MessageDigest
.getInstance("MD5");
digest.update(s.getBytes());
byte messageDigest[] = digest.digest();
// Create Hex String
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++)
hexString.append(Integer.toHexString(0xFF & messageDigest[i]));
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
result - 1865e62e7129927f6e4cd9bff104f0 (length 30) working method:
public static final String md5(final String toEncrypt) {
try {
final MessageDigest digest = MessageDigest.getInstance("md5");
digest.update(toEncrypt.getBytes());
final byte[] bytes = digest.digest();
final StringBuilder sb = new StringBuilder();
for (int i = 0; i < bytes.length; i++) {
sb.append(String.format("%02X", bytes[i]));
}
return sb.toString().toLowerCase();
} catch (Exception exc) {
return ""; // Impossibru!
}
}
result - 1865e62e7129927f6e4c0d9bff1004f0 (length 32)
private static char[] hextable = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
public static String byteArrayToHex(byte[] array) {
String s = "";
for (int i = 0; i < array.length; ++i) {
int di = (array[i] + 256) & 0xFF; // Make it unsigned
s = s + hextable[(di >> 4) & 0xF] + hextable[di & 0xF];
}
return s;
}
public static String digest(String s, String algorithm) {
MessageDigest m = null;
try {
m = MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return s;
}
m.update(s.getBytes(), 0, s.length());
return byteArrayToHex(m.digest());
}
public static String md5(String s) {
return digest(s, "MD5");
}
The answer above is almost 100% correct. It will fail with unicode.
MessageDigest digest;
try {
digest = MessageDigest.getInstance("MD5");
byte utf8_bytes[] = tag_xml.getBytes();
digest.update(utf8_bytes,0,utf8_bytes.length);
hash = new BigInteger(1, digest.digest()).toString(16);
}
catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
Need the length from the byte array not the string.
With @Donut solution, with UTF-8 encoded characters (eg: é) you have to use getBytes("UTF-8"). Here is my correction of the digest method:
private static char[] hextable = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
public static String byteArrayToHex(byte[] array) {
String s = "";
for (int i = 0; i < array.length; ++i) {
int di = (array[i] + 256) & 0xFF; // Make it unsigned
s = s + hextable[(di >> 4) & 0xF] + hextable[di & 0xF];
}
return s;
}
public static String digest(String s, String algorithm) {
MessageDigest m = null;
try {
m = MessageDigest.getInstance(algorithm);
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return s;
}
try {
m.update(s.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
m.update(s.getBytes());
}
return byteArrayToHex(m.digest());
}
public static String md5(String s) {
return digest(s, "MD5");
}
Donut's solution in a single function:
private static char[] hextable = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
private static String md5(String s)
{
MessageDigest digest;
try
{
digest = MessageDigest.getInstance("MD5");
digest.update(s.getBytes(), 0, s.length());
byte[] bytes = digest.digest();
String hash = "";
for (int i = 0; i < bytes.length; ++i)
{
int di = (bytes[i] + 256) & 0xFF;
hash = hash + hextable[(di >> 4) & 0xF] + hextable[di & 0xF];
}
return hash;
}
catch (NoSuchAlgorithmException e)
{
}
return "";
}
The following worked for me on Android without truncating any 0's infront:
MessageDigest md = null;
String digest = null;
try {
md = MessageDigest.getInstance("MD5");
byte[] hash = md.digest(myStringToEncode.getBytes("UTF-8")); //converting byte array to Hexadecimal String
StringBuilder sb = new StringBuilder(2*hash.length);
for(byte b : hash){
sb.append(String.format("%02x", b&0xff));
}
digest = sb.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return digest;
MessageDigest md = MessageDigest.getInstance("MD5");
md.update('yourstring');
byte[] digest = md.digest();
StringBuffer sb = new StringBuffer();
for (byte b : digest) {
sb.append(String.format("%02x", (0xFF & b)));
}
It's late for the author, but before this, I get Integer.toHexString(0xff&b) , which strips leading 0s from the hex string. It makes me struggled for a long time. Hope useful for some guys.
if you are using guava:
public String generateMd5(String input) {
HashFunction hf = Hashing.md5();
Hasher hasher = hf.newHasher();
HashCode hc = hasher.putString(input, StandardCharsets.UTF_8).hash();
return hc.toString();
}
If you didn't have security constraints and just wanted to convert String to a unique int. I'm writing it because that what I looked for and reached here.
String my_key
int my_key.hashCode()
if you have up to 10 chars it will even be unique See also https://stackoverflow.com/a/17583653/1984636
This not missing '0'
public static String md5(String string) {
if (TextUtils.isEmpty(string)) {
return "";
}
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
byte[] bytes = md5.digest(string.getBytes());
String result = "";
for (byte b : bytes) {
String temp = Integer.toHexString(b & 0xff);
if (temp.length() == 1) {
temp = "0" + temp;
}
result += temp;
}
return result;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return "";
}
原文出處:java - How to hash a string in Android? - Stack Overflow
|
|
|