java加密算法研究

●  BASE64 严格地说,属于编码格式,而非加密算法
    ●  MD5(Message Digest algorithm 5,信息摘要算法)
    ●  SHA(Secure Hash Algorithm,安全散列算法)
    ●  HMAC(Hash Message Authentication Code,散列消息鉴别码)复杂的对称加密(DES、PBE)、非对称加密算法:
    ●  DES(Data Encryption Standard,数据加密算法)
    ●  PBE(Password-based encryption,基于密码验证)
    ●  RSA(算法的名字以发明者的名字命名:Ron Rivest, AdiShamir 和Leonard Adleman)
    ●  DH(Diffie-Hellman算法,密钥一致协议)
    ●  DSA(Digital Signature Algorithm,数字签名)
    ●  ECC(Elliptic Curves Cryptography,椭圆曲线密码编码学)[/size]

-------------------------------------------------------------------------------------------------------------------------------------------

本篇内容简要介绍BASE64、MD5、SHA、HMAC几种加密算法。 
    BASE64编码算法不算是真正的加密算法。 
    MD5、SHA、HMAC这三种加密算法,可谓是非可逆加密,就是不可解密的加密方法,我们称之为单向加密算法。我们通常只把他们作为加密的基础。单纯的以上三种的加密并不可靠。

BASE64 
按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.) 
常见于邮件、http加密,截取http信息,你就会发现登录操作的用户名、密码字段通过BASE64加密的。


 
主要就是BASE64Encoder、BASE64Decoder两个类,我们只需要知道使用对应的方法即可。另,BASE加密后产生的字节位数是8的倍数,如果不够位数以=符号填充。

sun不推荐使用它们自己的base64,所以用apache的挺好!

MD5 
MD5 -- message-digest algorithm 5 (信息-摘要算法)缩写,广泛用于加密和解密技术,常用于文件校验。校验?不管文件多大,经过MD5后都能生成唯一的MD5值。好比现在的ISO校验,都是MD5校验。怎么用?当然是把ISO经过MD5后产生MD5的值。一般下载linux-ISO的朋友都见过下载链接旁边放着MD5的串。就是用来验证文件是否一致的。


 
通常我们不直接使用上述MD5加密。通常将MD5产生的字节数组交给BASE64再加密一把,得到相应的字符串。

SHA 
SHA(Secure Hash Algorithm,安全散列算法),数字签名等密码学应用中重要的工具,被广泛地应用于电子商务等信息安全领域。虽然,SHA与MD5通过碰撞法都被破解了,但是SHA仍然是公认的安全加密算法,较之MD5更为安全。


 
HMAC 
HMAC(Hash Message Authentication Code,散列消息鉴别码,基于密钥的Hash算法的认证协议。消息鉴别码实现鉴别的原理是,用公开函数和密钥产生一个固定长度的值作为认证标识,用这个标识鉴别消息的完整性。使用一个密钥生成一个固定大小的小数据块,即MAC,并将其加入到消息中,然后传输。接收方利用与发送方共享的密钥进行鉴别认证等。


 
  BASE64的加密解密是双向的,可以求反解。 
    MD5、SHA以及HMAC是单向加密,任何数据加密后只会产生唯一的一个加密串,通常用来校验数据在传输过程中是否被修改。其中HMAC算法有一个密钥,增强了数据传输过程中的安全性,强化了算法外的不可控因素。[img]http://www.iteye.com/images/smiles/icon_biggrin.gif" alt="[/img] 
    单向加密的用途主要是为了校验数据在传输过程中是否被修改。

代码如下:

Java代码  

  1. import java.math.BigInteger;
  2. import java.security.InvalidKeyException;
  3. import java.security.MessageDigest;
  4. import java.security.NoSuchAlgorithmException;
  5. import javax.crypto.KeyGenerator;
  6. import javax.crypto.Mac;
  7. import javax.crypto.SecretKey;
  8. import javax.crypto.spec.SecretKeySpec;
  9. import org.apache.commons.codec.binary.Base64;
  10. public class MyEncrypt {
  11. public static final String KEY_SHA = "SHA";
  12. public static final String KEY_MD5 = "MD5";
  13. public static final String KEY_MAC = "HmacMD5";
  14. // sun不推荐使用它们自己的base64,用apache的挺好
  15. /**
  16. * BASE64解密
  17. */
  18. public static byte[] decryptBASE64(byte[] dest) {
  19. if (dest == null) {
  20. return null;
  21. }
  22. return Base64.decodeBase64(dest);
  23. }
  24. /**
  25. * BASE64加密
  26. */
  27. public static byte[] encryptBASE64(byte[] origin) {
  28. if (origin == null) {
  29. return null;
  30. }
  31. return Base64.encodeBase64(origin);
  32. }
  33. /**
  34. * MD5加密
  35. *
  36. * @throws NoSuchAlgorithmException
  37. */
  38. public static byte[] encryptMD5(byte[] data)
  39. throws NoSuchAlgorithmException {
  40. if (data == null) {
  41. return null;
  42. }
  43. MessageDigest md5 = MessageDigest.getInstance(KEY_MD5);
  44. md5.update(data);
  45. return md5.digest();
  46. }
  47. /**
  48. * SHA加密
  49. *
  50. * @throws NoSuchAlgorithmException
  51. */
  52. public static byte[] encryptSHA(byte[] data)
  53. throws NoSuchAlgorithmException {
  54. if (data == null) {
  55. return null;
  56. }
  57. MessageDigest sha = MessageDigest.getInstance(KEY_SHA);
  58. sha.update(data);
  59. return sha.digest();
  60. }
  61. /**
  62. * 初始化HMAC密钥
  63. *
  64. * @throws NoSuchAlgorithmException
  65. */
  66. public static String initMacKey() throws NoSuchAlgorithmException {
  67. KeyGenerator keyGenerator = KeyGenerator.getInstance(KEY_MAC);
  68. SecretKey secretKey = keyGenerator.generateKey();
  69. return new String(encryptBASE64(secretKey.getEncoded()));
  70. }
  71. /**
  72. * HMAC加密
  73. *
  74. * @throws NoSuchAlgorithmException
  75. * @throws InvalidKeyException
  76. */
  77. public static byte[] encryptHMAC(byte[] data, String key)
  78. throws NoSuchAlgorithmException, InvalidKeyException {
  79. SecretKey secretKey = new SecretKeySpec(decryptBASE64(key.getBytes()),
  80. KEY_MAC);
  81. Mac mac = Mac.getInstance(secretKey.getAlgorithm());
  82. mac.init(secretKey);
  83. return mac.doFinal(data);
  84. }
  85. public static void main(String[] args) throws Exception {
  86. // TODO Auto-generated method stub
  87. String data = "简单加密";
  88. System.out.println(new BigInteger(encryptBASE64(data.getBytes())).toString(16));
  89. System.out.println(new BigInteger(encryptBASE64(data.getBytes())).toString(32));
  90. System.out.println(new String(decryptBASE64(encryptBASE64(data.getBytes()))));
  91. System.out.println(new BigInteger(encryptMD5(data.getBytes())).toString());
  92. System.out.println(new BigInteger(encryptSHA(data.getBytes())).toString());
  93. System.out.println(new BigInteger(encryptHMAC(data.getBytes(), initMacKey())).toString());
  94. }
  95. }

------------------------------------------------------------------------------------------------------------------------------------------------------------

可变MD5加密(Java实现)

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

Java代码  

  1. import java.security.MessageDigest;
  2. /**
  3. * 标准MD5加密方法,使用java类库的security包的MessageDigest类处理
  4. */
  5. public class MD5 {
  6. /**
  7. * 获得MD5加密密码的方法
  8. */
  9. public static String getMD5ofStr(String origString) {
  10. String origMD5 = null;
  11. try {
  12. MessageDigest md5 = MessageDigest.getInstance("MD5");
  13. // md5.update(origString.getBytes());
  14. byte[] result = md5.digest(origString.getBytes());
  15. origMD5 = byteArray2HexStr(result);
  16. // if ("123".equals(origString)) {
  17. // System.out.println(new String(result));
  18. // System.out.println(new BigInteger(result).toString(16));
  19. // }
  20. } catch (Exception e) {
  21. e.printStackTrace();
  22. }
  23. return origMD5;
  24. }
  25. /**
  26. * 处理字节数组得到MD5密码的方法
  27. */
  28. private static String byteArray2HexStr(byte[] bs) {
  29. StringBuffer sb = new StringBuffer();
  30. for (byte b : bs) {
  31. sb.append(byte2HexStr(b));
  32. }
  33. return sb.toString();
  34. }
  35. /**
  36. * 字节标准移位转十六进制方法
  37. */
  38. private static String byte2HexStr(byte b) {
  39. String hexStr = null;
  40. int n = b;
  41. if (n < 0) {
  42. // 若需要自定义加密,请修改这个移位算法即可
  43. n = b & 0x7F + 128;
  44. }
  45. hexStr = Integer.toHexString(n / 16) + Integer.toHexString(n % 16);
  46. return hexStr.toUpperCase();
  47. }
  48. /**
  49. * 提供一个MD5多次加密方法
  50. */
  51. public static String getMD5ofStr(String origString, int times) {
  52. String md5 = getMD5ofStr(origString);
  53. for (int i = 0; i < times - 1; i++) {
  54. md5 = getMD5ofStr(md5);
  55. }
  56. return getMD5ofStr(md5);
  57. }
  58. /**
  59. * 密码验证方法
  60. */
  61. public static boolean verifyPassword(String inputStr, String MD5Code) {
  62. return getMD5ofStr(inputStr).equals(MD5Code);
  63. }
  64. /**
  65. * 重载一个多次加密时的密码验证方法
  66. */
  67. public static boolean verifyPassword(String inputStr, String MD5Code,
  68. int times) {
  69. return getMD5ofStr(inputStr, times).equals(MD5Code);
  70. }
  71. /**
  72. * 提供一个测试的主函数
  73. */
  74. public static void main(String[] args) {
  75. System.out.println("123:" + getMD5ofStr("123"));
  76. System.out.println("123456789:" + getMD5ofStr("123456789"));
  77. System.out.println("sarin:" + getMD5ofStr("sarin"));
  78. System.out.println("123:" + getMD5ofStr("123", 4));
  79. }
  80. }

可以看出实现的过程非常简单,因为由java类库提供了处理支持。但是要清楚的是这种方式产生的密码不是标准的MD5码,它需要进行移位处理才能得到标准MD5码。这个程序的关键之处也在这了,怎么可变?调整移位算法不就可变了么!不进行移位,也能够得到32位的密码,这就不是标准加密了,只要加密和验证过程使用相同的算法就可以了。 
    MD5加密还是很安全的,像CMD5那些穷举破解的只是针对标准MD5加密的结果进行的,如果自定义移位算法后,它还有效么?可以说是无解的了,所以MD5非常安全可靠。 
    为了更可变,还提供了多次加密的方法,可以在MD5基础之上继续MD5,就是对32位的第一次加密结果再MD5,恩,这样去破解?没有任何意义。 
    这样在MIS系统中使用,安全可靠,欢迎交流,希望对使用者有用。 
    我们最后看看由MD5加密算法实现的类,那是非常庞大的。

Java代码  

  1. import java.lang.reflect.*;
  2. /**
  3. * **********************************************
  4. * md5 类实现了RSA Data Security, Inc.在提交给IETF
  5. * 的RFC1321中的MD5 message-digest 算法。
  6. * ***********************************************
  7. */
  8. public class MD5 {
  9. /* 下面这些S11-S44实际上是一个4*4的矩阵,在原始的C实现中是用#define 实现的,
  10. 这里把它们实现成为static final是表示了只读,切能在同一个进程空间内的多个
  11. Instance间共享*/
  12. static final int S11 = 7;
  13. static final int S12 = 12;
  14. static final int S13 = 17;
  15. static final int S14 = 22;
  16. static final int S21 = 5;
  17. static final int S22 = 9;
  18. static final int S23 = 14;
  19. static final int S24 = 20;
  20. static final int S31 = 4;
  21. static final int S32 = 11;
  22. static final int S33 = 16;
  23. static final int S34 = 23;
  24. static final int S41 = 6;
  25. static final int S42 = 10;
  26. static final int S43 = 15;
  27. static final int S44 = 21;
  28. static final byte[] PADDING = { -128, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  29. 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  30. 0 };
  31. /* 下面的三个成员是MD5计算过程中用到的3个核心数据,在原始的C实现中
  32. 被定义到MD5_CTX结构中
  33. */
  34. private long[] state = new long[4]; // state (ABCD)
  35. private long[] count = new long[2]; // number of bits, modulo 2^64 (lsb first)
  36. private byte[] buffer = new byte[64]; // input buffer
  37. /* digestHexStr是MD5的唯一一个公共成员,是最新一次计算结果的
  38.   16进制ASCII表示.
  39. */
  40. public String digestHexStr;
  41. /* digest,是最新一次计算结果的2进制内部表示,表示128bit的MD5值.
  42. */
  43. private byte[] digest = new byte[16];
  44. /*
  45. getMD5ofStr是类MD5最主要的公共方法,入口参数是你想要进行MD5变换的字符串
  46. 返回的是变换完的结果,这个结果是从公共成员digestHexStr取得的.
  47. */
  48. public String getMD5ofStr(String inbuf) {
  49. md5Init();
  50. md5Update(inbuf.getBytes(), inbuf.length());
  51. md5Final();
  52. digestHexStr = "";
  53. for (int i = 0; i < 16; i++) {
  54. digestHexStr += byteHEX(digest[i]);
  55. }
  56. return digestHexStr;
  57. }
  58. // 这是MD5这个类的标准构造函数,JavaBean要求有一个public的并且没有参数的构造函数
  59. public MD5() {
  60. md5Init();
  61. return;
  62. }
  63. /* md5Init是一个初始化函数,初始化核心变量,装入标准的幻数 */
  64. private void md5Init() {
  65. count[0] = 0L;
  66. count[1] = 0L;
  67. ///* Load magic initialization constants.
  68. state[0] = 0x67452301L;
  69. state[1] = 0xefcdab89L;
  70. state[2] = 0x98badcfeL;
  71. state[3] = 0x10325476L;
  72. return;
  73. }
  74. /* F, G, H ,I 是4个基本的MD5函数,在原始的MD5的C实现中,由于它们是
  75. 简单的位运算,可能出于效率的考虑把它们实现成了宏,在java中,我们把它们
  76. 实现成了private方法,名字保持了原来C中的。 */
  77. private long F(long x, long y, long z) {
  78. return (x & y) | ((~x) & z);
  79. }
  80. private long G(long x, long y, long z) {
  81. return (x & z) | (y & (~z));
  82. }
  83. private long H(long x, long y, long z) {
  84. return x ^ y ^ z;
  85. }
  86. private long I(long x, long y, long z) {
  87. return y ^ (x | (~z));
  88. }
  89. /*
  90. FF,GG,HH和II将调用F,G,H,I进行近一步变换
  91. FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
  92. Rotation is separate from addition to prevent recomputation.
  93. */
  94. private long FF(long a, long b, long c, long d, long x, long s, long ac) {
  95. a += F(b, c, d) + x + ac;
  96. a = ((int) a << s) | ((int) a >>> (32 - s));
  97. a += b;
  98. return a;
  99. }
  100. private long GG(long a, long b, long c, long d, long x, long s, long ac) {
  101. a += G(b, c, d) + x + ac;
  102. a = ((int) a << s) | ((int) a >>> (32 - s));
  103. a += b;
  104. return a;
  105. }
  106. private long HH(long a, long b, long c, long d, long x, long s, long ac) {
  107. a += H(b, c, d) + x + ac;
  108. a = ((int) a << s) | ((int) a >>> (32 - s));
  109. a += b;
  110. return a;
  111. }
  112. private long II(long a, long b, long c, long d, long x, long s, long ac) {
  113. a += I(b, c, d) + x + ac;
  114. a = ((int) a << s) | ((int) a >>> (32 - s));
  115. a += b;
  116. return a;
  117. }
  118. /*
  119. md5Update是MD5的主计算过程,inbuf是要变换的字节串,inputlen是长度,这个
  120. 函数由getMD5ofStr调用,调用之前需要调用md5init,因此把它设计成private的
  121. */
  122. private void md5Update(byte[] inbuf, int inputLen) {
  123. int i, index, partLen;
  124. byte[] block = new byte[64];
  125. index = (int) (count[0] >>> 3) & 0x3F;
  126. // /* Update number of bits */
  127. if ((count[0] += (inputLen << 3)) < (inputLen << 3))
  128. count[1]++;
  129. count[1] += (inputLen >>> 29);
  130. partLen = 64 - index;
  131. // Transform as many times as possible.
  132. if (inputLen >= partLen) {
  133. md5Memcpy(buffer, inbuf, index, 0, partLen);
  134. md5Transform(buffer);
  135. for (i = partLen; i + 63 < inputLen; i += 64) {
  136. md5Memcpy(block, inbuf, 0, i, 64);
  137. md5Transform(block);
  138. }
  139. index = 0;
  140. } else
  141. i = 0;
  142. ///* Buffer remaining input */
  143. md5Memcpy(buffer, inbuf, index, i, inputLen - i);
  144. }
  145. /*
  146. md5Final整理和填写输出结果
  147. */
  148. private void md5Final() {
  149. byte[] bits = new byte[8];
  150. int index, padLen;
  151. ///* Save number of bits */
  152. Encode(bits, count, 8);
  153. ///* Pad out to 56 mod 64.
  154. index = (int) (count[0] >>> 3) & 0x3f;
  155. padLen = (index < 56) ? (56 - index) : (120 - index);
  156. md5Update(PADDING, padLen);
  157. ///* Append length (before padding) */
  158. md5Update(bits, 8);
  159. ///* Store state in digest */
  160. Encode(digest, state, 16);
  161. }
  162. /* md5Memcpy是一个内部使用的byte数组的块拷贝函数,从input的inpos开始把len长度的
  163.   字节拷贝到output的outpos位置开始
  164. */
  165. private void md5Memcpy(byte[] output, byte[] input, int outpos, int inpos, int len) {
  166. int i;
  167. for (i = 0; i < len; i++)
  168. output[outpos + i] = input[inpos + i];
  169. }
  170. /*
  171. md5Transform是MD5核心变换程序,有md5Update调用,block是分块的原始字节
  172. */
  173. private void md5Transform(byte block[]) {
  174. long a = state[0], b = state[1], c = state[2], d = state[3];
  175. long[] x = new long[16];
  176. Decode(x, block, 64);
  177. /* Round 1 */
  178. a = FF(a, b, c, d, x[0], S11, 0xd76aa478L); /* 1 */
  179. d = FF(d, a, b, c, x[1], S12, 0xe8c7b756L); /* 2 */
  180. c = FF(c, d, a, b, x[2], S13, 0x242070dbL); /* 3 */
  181. b = FF(b, c, d, a, x[3], S14, 0xc1bdceeeL); /* 4 */
  182. a = FF(a, b, c, d, x[4], S11, 0xf57c0fafL); /* 5 */
  183. d = FF(d, a, b, c, x[5], S12, 0x4787c62aL); /* 6 */
  184. c = FF(c, d, a, b, x[6], S13, 0xa8304613L); /* 7 */
  185. b = FF(b, c, d, a, x[7], S14, 0xfd469501L); /* 8 */
  186. a = FF(a, b, c, d, x[8], S11, 0x698098d8L); /* 9 */
  187. d = FF(d, a, b, c, x[9], S12, 0x8b44f7afL); /* 10 */
  188. c = FF(c, d, a, b, x[10], S13, 0xffff5bb1L); /* 11 */
  189. b = FF(b, c, d, a, x[11], S14, 0x895cd7beL); /* 12 */
  190. a = FF(a, b, c, d, x[12], S11, 0x6b901122L); /* 13 */
  191. d = FF(d, a, b, c, x[13], S12, 0xfd987193L); /* 14 */
  192. c = FF(c, d, a, b, x[14], S13, 0xa679438eL); /* 15 */
  193. b = FF(b, c, d, a, x[15], S14, 0x49b40821L); /* 16 */
  194. /* Round 2 */
  195. a = GG(a, b, c, d, x[1], S21, 0xf61e2562L); /* 17 */
  196. d = GG(d, a, b, c, x[6], S22, 0xc040b340L); /* 18 */
  197. c = GG(c, d, a, b, x[11], S23, 0x265e5a51L); /* 19 */
  198. b = GG(b, c, d, a, x[0], S24, 0xe9b6c7aaL); /* 20 */
  199. a = GG(a, b, c, d, x[5], S21, 0xd62f105dL); /* 21 */
  200. d = GG(d, a, b, c, x[10], S22, 0x2441453L); /* 22 */
  201. c = GG(c, d, a, b, x[15], S23, 0xd8a1e681L); /* 23 */
  202. b = GG(b, c, d, a, x[4], S24, 0xe7d3fbc8L); /* 24 */
  203. a = GG(a, b, c, d, x[9], S21, 0x21e1cde6L); /* 25 */
  204. d = GG(d, a, b, c, x[14], S22, 0xc33707d6L); /* 26 */
  205. c = GG(c, d, a, b, x[3], S23, 0xf4d50d87L); /* 27 */
  206. b = GG(b, c, d, a, x[8], S24, 0x455a14edL); /* 28 */
  207. a = GG(a, b, c, d, x[13], S21, 0xa9e3e905L); /* 29 */
  208. d = GG(d, a, b, c, x[2], S22, 0xfcefa3f8L); /* 30 */
  209. c = GG(c, d, a, b, x[7], S23, 0x676f02d9L); /* 31 */
  210. b = GG(b, c, d, a, x[12], S24, 0x8d2a4c8aL); /* 32 */
  211. /* Round 3 */
  212. a = HH(a, b, c, d, x[5], S31, 0xfffa3942L); /* 33 */
  213. d = HH(d, a, b, c, x[8], S32, 0x8771f681L); /* 34 */
  214. c = HH(c, d, a, b, x[11], S33, 0x6d9d6122L); /* 35 */
  215. b = HH(b, c, d, a, x[14], S34, 0xfde5380cL); /* 36 */
  216. a = HH(a, b, c, d, x[1], S31, 0xa4beea44L); /* 37 */
  217. d = HH(d, a, b, c, x[4], S32, 0x4bdecfa9L); /* 38 */
  218. c = HH(c, d, a, b, x[7], S33, 0xf6bb4b60L); /* 39 */
  219. b = HH(b, c, d, a, x[10], S34, 0xbebfbc70L); /* 40 */
  220. a = HH(a, b, c, d, x[13], S31, 0x289b7ec6L); /* 41 */
  221. d = HH(d, a, b, c, x[0], S32, 0xeaa127faL); /* 42 */
  222. c = HH(c, d, a, b, x[3], S33, 0xd4ef3085L); /* 43 */
  223. b = HH(b, c, d, a, x[6], S34, 0x4881d05L); /* 44 */
  224. a = HH(a, b, c, d, x[9], S31, 0xd9d4d039L); /* 45 */
  225. d = HH(d, a, b, c, x[12], S32, 0xe6db99e5L); /* 46 */
  226. c = HH(c, d, a, b, x[15], S33, 0x1fa27cf8L); /* 47 */
  227. b = HH(b, c, d, a, x[2], S34, 0xc4ac5665L); /* 48 */
  228. /* Round 4 */
  229. a = II(a, b, c, d, x[0], S41, 0xf4292244L); /* 49 */
  230. d = II(d, a, b, c, x[7], S42, 0x432aff97L); /* 50 */
  231. c = II(c, d, a, b, x[14], S43, 0xab9423a7L); /* 51 */
  232. b = II(b, c, d, a, x[5], S44, 0xfc93a039L); /* 52 */
  233. a = II(a, b, c, d, x[12], S41, 0x655b59c3L); /* 53 */
  234. d = II(d, a, b, c, x[3], S42, 0x8f0ccc92L); /* 54 */
  235. c = II(c, d, a, b, x[10], S43, 0xffeff47dL); /* 55 */
  236. b = II(b, c, d, a, x[1], S44, 0x85845dd1L); /* 56 */
  237. a = II(a, b, c, d, x[8], S41, 0x6fa87e4fL); /* 57 */
  238. d = II(d, a, b, c, x[15], S42, 0xfe2ce6e0L); /* 58 */
  239. c = II(c, d, a, b, x[6], S43, 0xa3014314L); /* 59 */
  240. b = II(b, c, d, a, x[13], S44, 0x4e0811a1L); /* 60 */
  241. a = II(a, b, c, d, x[4], S41, 0xf7537e82L); /* 61 */
  242. d = II(d, a, b, c, x[11], S42, 0xbd3af235L); /* 62 */
  243. c = II(c, d, a, b, x[2], S43, 0x2ad7d2bbL); /* 63 */
  244. b = II(b, c, d, a, x[9], S44, 0xeb86d391L); /* 64 */
  245. state[0] += a;
  246. state[1] += b;
  247. state[2] += c;
  248. state[3] += d;
  249. }
  250. /*Encode把long数组按顺序拆成byte数组,因为java的long类型是64bit的,
  251. 只拆低32bit,以适应原始C实现的用途
  252. */
  253. private void Encode(byte[] output, long[] input, int len) {
  254. int i, j;
  255. for (i = 0, j = 0; j < len; i++, j += 4) {
  256. output[j] = (byte) (input[i] & 0xffL);
  257. output[j + 1] = (byte) ((input[i] >>> 8) & 0xffL);
  258. output[j + 2] = (byte) ((input[i] >>> 16) & 0xffL);
  259. output[j + 3] = (byte) ((input[i] >>> 24) & 0xffL);
  260. }
  261. }
  262. /*Decode把byte数组按顺序合成成long数组,因为java的long类型是64bit的,
  263. 只合成低32bit,高32bit清零,以适应原始C实现的用途
  264. */
  265. private void Decode(long[] output, byte[] input, int len) {
  266. int i, j;
  267. for (i = 0, j = 0; j < len; i++, j += 4)
  268. output[i] = b2iu(input[j]) | (b2iu(input[j + 1]) << 8) | (b2iu(input[j + 2]) << 16)
  269. | (b2iu(input[j + 3]) << 24);
  270. return;
  271. }
  272. /*
  273. b2iu是我写的一个把byte按照不考虑正负号的原则的"升位"程序,因为java没有unsigned运算
  274. */
  275. public static long b2iu(byte b) {
  276. return b < 0 ? b & 0x7F + 128 : b;
  277. }
  278. /*byteHEX(),用来把一个byte类型的数转换成十六进制的ASCII表示,
  279.  因为java中的byte的toString无法实现这一点,我们又没有C语言中的
  280. sprintf(outbuf,"%02X",ib)
  281. */
  282. public static String byteHEX(byte ib) {
  283. char[] Digit = { ‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘, ‘A‘, ‘B‘, ‘C‘, ‘D‘, ‘E‘, ‘F‘ };
  284. char[] ob = new char[2];
  285. ob[0] = Digit[(ib >>> 4) & 0X0F];
  286. ob[1] = Digit[ib & 0X0F];
  287. String s = new String(ob);
  288. return s;
  289. }
  290. public static void main(String args[]) {
  291. MD5 m = new MD5();
  292. if (Array.getLength(args) == 0) { //如果没有参数,执行标准的Test Suite
  293. System.out.println("MD5 Test suite:");
  294. System.out.println("MD5(\"\"):" + m.getMD5ofStr(""));
  295. System.out.println("MD5(\"a\"):" + m.getMD5ofStr("a"));
  296. System.out.println("MD5(\"abc\"):" + m.getMD5ofStr("abc"));
  297. System.out.println("MD5(\"11\"):" + m.getMD5ofStr("11"));
  298. System.out.println("MD5(\"123\"):" + m.getMD5ofStr("123"));
  299. System.out.println("MD5(\"message digest\"):" + m.getMD5ofStr("message digest"));
  300. System.out.println("MD5(\"abcdefghijklmnopqrstuvwxyz\"):" + m.getMD5ofStr("abcdefghijklmnopqrstuvwxyz"));
  301. System.out.println("MD5(\"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789\"):"
  302. + m.getMD5ofStr("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"));
  303. } else
  304. System.out.println("MD5(" + args[0] + ")=" + m.getMD5ofStr(args[0]));
  305. }
  306. }

java加密算法研究

时间: 2024-08-12 02:19:13

java加密算法研究的相关文章

java加密算法小结(2)--MD5加密算法

上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇来整理一下一个被广泛应用的加密算法---MD5. 简单了解 MD5(Message Digest Algorithm 5),翻译过来是消息摘要算法第五版,按照惯例,我们推理可能也有MD2,MD3这样名字的历史版本.. 即使完全不了解这个算法的原理,我们也可以从命名中看出一些眉道,所谓摘要,就是一个简短的概括,像我写过的毕业论文,上来第一部分就是摘要,它对后面长篇大论的文章做了一个简短有力的概

java加密算法小结--MD5加密算法

上一篇文章整理了Base64算法的相关知识,严格来说,Base64只能算是一种编码方式而非加密算法,这一篇来整理一下一个被广泛应用的加密算法---MD5. 简单了解 MD5(Message Digest Algorithm 5),翻译过来是消息摘要算法第五版,按照惯例,我们推理可能也有MD2,MD3这样名字的历史版本.. 即使完全不了解这个算法的原理,我们也可以从命名中看出一些眉道,所谓摘要,就是一个简短的概括,像我写过的毕业论文,上来第一部分就是摘要,它对后面长篇大论的文章做了一个简短有力的概

Java加密算法 RSA

Java加密算法 RSA 2015-06-06 08:44 511人阅读 评论(0) 收藏 举报  分类: JAVA(57)  公钥加密也称为非对称加密.速度慢.加密和解密的钥匙不相同,某一个人持有私钥,任何人都可以知道公钥 [java] view plaincopy package com.stone.security; import java.security.KeyPair; import java.security.KeyPairGenerator; import java.securi

java注解研究

注解作用 常见的作用有以下几种: 生成文档.这是最常见的,也是java 最早提供的注解.常用的有@see @param @return @author等. 跟踪代码依赖性,实现替代配置文件功能.比较常见的是spring 2.5 开始的基于注解配置.作用就是减少配置.现在的框架基本都使用了这种配置来减少配置文件的数量.也是 在编译时进行格式检查.如@override 放在方法前,如果你这个方法并不是覆盖了超类方法,则编译时就能检查出. 包 java.lang.annotation 中包含所有定义自

java加密算法入门(三)-非对称加密详解

1.简单介绍 这几天一直在看非对称的加密,相比之前的两篇内容,这次看了两倍多的时间还云里雾里的,所以这篇文章相对之前的两篇,概念性的东西多了些,另外是代码的每一步我都做了介绍,方便自己以后翻阅,也方便大家理解.最后就是关于代码的demo,DH算法.RSA算法本文中只有最基础的用法,实际在工作中可能会涉及到密钥的转换X509EncodedKeySpec和PKCS8EncodedKeySpec,相关的demo名分别叫DH2Test,RSA2Test,已经上传GIT.如果对您有帮助,请给我个star.

java线程研究---(8)Thread同步:锁的概念

(多线程数据共用的)示例代码: 先来看看"java线程研究---(7)Thread同步:多线程数据共用会产生问题"这篇文章里面主要的代码例子 ShareDataThread.java package thread; public class ShareDataThread implements Runnable { private int i = 0; @Override public void run() { while (i < 10) { i++; for (int j =

[转]Java加密算法

如基本的单向加密算法: BASE64 严格地说,属于编码格式,而非加密算法 MD5(Message Digest algorithm 5,信息摘要算法) SHA(Secure Hash Algorithm,安全散列算法) HMAC(Hash Message Authentication Code,散列消息鉴别码) 复杂的对称加密(DES.PBE).非对称加密算法: DES(Data Encryption Standard,数据加密算法) PBE(Password-based encryption

JAVA 加密算法初探DES&amp;AES

开发项目中需要将重要数据缓存在本地以便在离线是读取,如果不对数据进行处理,很容易造成损失.所以,我们一般对此类数据进行加密处理.这里,主要介绍两种简单的加密算法:DES&AES. 先简单介绍一下一般的加密方案(如下图所示): 1)明文:原始信息. 2)加密算法:以密钥为参数,对明文进行多种置换和转换的规则和步骤,变换结果为密文. 3)密钥:加密与解密算法的参数,直接影响对明文进行变换的结果. 4)密文:对明文进行变换的结果. 5)解密算法:加密算法的逆变换,以密文为输入.密钥为参数,变换结果为明

JAVA深入研究——Method的Invoke方法。

在写代码的时候,发现从父类class通过getDeclaredMethod获取的Method可以调用子类的对象,而子类改写了这个方法,从子类class通过getDeclaredMethod也能获取到Method,这时去调用父类的对象也会报错.虽然这是很符合多态的现象,也符合java的动态绑定规范,但还是想弄懂java是如何实现的,就学习了下Method的源代码. Method的invoke方法 1.先检查 AccessibleObject的override属性是否为true. Accessibl