在做登录功能时要对密码加密, 而java后台使用的Md5PasswordEncoder.java计算密文。 蛋疼的是Android压根没这个类, 怎么破?
源代码:http://www.grepcode.com/file/repo1.maven.org/maven2/org.springframework.security/spring-security-core/4.0.2.RELEASE/org/springframework/security/authentication/encoding/Md5PasswordEncoder.java#Md5PasswordEncoder.java
后台的加密代码:
String password="123";
Md5PasswordEncoder encoder = new Md5PasswordEncoder();
String cryptoPass = encoder.encodePassword(password,username);
测试用例:
user: zhangsan
pwd: 123
加密后pwd: b2316c0d1ff0550298121a537ab93f21
先看下MessageDigestPasswordEncoder.java加密函数, 用户名是盐值, 最终生成盐值MD5:
public String encodePassword(String rawPass, Object salt) {
String saltedPass = mergePasswordAndSalt(rawPass, salt, false); //字符串拼接成rawPass{salt}格式
MessageDigest messageDigest = getMessageDigest(); //就是MessageDigest.getInstance
byte[] digest = messageDigest.digest(Utf8.encode(saltedPass)); //转换成utf-8格式字节流
// "stretch" the encoded value if configured to do so
for (int i = 1; i < iterations; i++) {
digest = messageDigest.digest(digest); //iterations的初值是1, 所以不会进来
}
if (getEncodeHashAsBase64()) { //该函数默认返回false
return Utf8.decode(Base64.encode(digest));
} else {
return new String(Hex.encode(digest)); //最终执行这一行
}
}
最终android实现参考代码:
private static final char[] HEX = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; public static char[] encode(byte[] bytes) { final int nBytes = bytes.length; char[] result = new char[2 * nBytes]; int j = 0; for (int i = 0; i < nBytes; i++) { // Char for top 4 bits result[j++] = HEX[(0xF0 & bytes[i]) >>> 4]; // Bottom 4 result[j++] = HEX[(0x0F & bytes[i])]; } return result; } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); String saltPass = "123{zhangsan}"; try { byte[] bytes = saltPass.getBytes("utf-8"); MessageDigest digest = MessageDigest.getInstance("MD5"); byte[] digestBytes = digest.digest(bytes); String encrupt = new String(encode(digestBytes)); Log.d("gr", "encrupt: " + encrupt); } catch (Exception ex) { } }日志:
08-23 16:04:20.678 1154-1154/gr.testactivity D/gr: encrupt: b2316c0d1ff0550298121a537ab93f21
android加密结果跟后台java是一致的! 因为是为了测试, 没有做封装。 不过稍微改一下就可以集成到登录界面里了。
#import <CommonCrypto/CommonDigest.h>
#import <Foundation/Foundation.h>
+(NSString *) md5: (NSString *) inPutText
{
constchar *cStr = [inPutTextUTF8String];
unsignedchar result[CC_MD5_DIGEST_LENGTH];
CC_MD5(cStr,strlen(cStr), result);
return [[NSStringstringWithFormat:@"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
result[0], result[1], result[2], result[3],
result[4], result[5], result[6], result[7],
result[8], result[9], result[10], result[11],
result[12], result[13], result[14], result[15]
] lowercaseString];
}
NSString *ptr =@"123{zhangsan}";
NSLog(@"盐值:%@", [Demo1 md5:ptr]);
2016-08-24 14:32:46.382 TestIos[3315:267507] 盐值:b2316c0d1ff0550298121a537ab93f21
我的微信公众号, 欢迎关注, 让我们一起成长