【转载】Android移动端与PHP服务端对称加密解密的实现

原文出处:Encryption between Java/Android And PHP 转载请注明原出处,尊重作者的原创,谢谢。

在网上找了很多实现,绝大多数都是不可用的,即android端和PHP端对同一字符串加密生成不一样的密文。但这个版本经测试是可用的,android版本:4.0.4,PHP5。

PHP类实现

 1 <?
 2 class ApiCrypter
 3 {
 4     private $iv  = 'fdsfds85435nfdfs'; #与JAVA实现类中的设置必须一致
 5     private $key = '89432hjfsd891787'; #与JAVA实现类中的设置必须一致
 6 
 7     public function __construct() {
 8     }
 9 
10     public function encrypt($str) { 
11       $str = $this->pkcs5_pad($str);   
12       $iv = $this->iv; 
13       $td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv); 
14       mcrypt_generic_init($td, $this->key, $iv);
15       $encrypted = mcrypt_generic($td, $str); 
16       mcrypt_generic_deinit($td);
17       mcrypt_module_close($td); 
18       return bin2hex($encrypted);
19     }
20 
21     public function decrypt($code) { 
22       $code = $this->hex2bin($code);
23       $iv = $this->iv; 
24       $td = mcrypt_module_open('rijndael-128', '', 'cbc', $iv); 
25       mcrypt_generic_init($td, $this->key, $iv);
26       $decrypted = mdecrypt_generic($td, $code); 
27       mcrypt_generic_deinit($td);
28       mcrypt_module_close($td); 
29       $ut =  utf8_encode(trim($decrypted));
30       return $this->pkcs5_unpad($ut);
31     }
32 
33     protected function hex2bin($hexdata) {
34       $bindata = ''; 
35       for ($i = 0; $i < strlen($hexdata); $i += 2) {
36           $bindata .= chr(hexdec(substr($hexdata, $i, 2)));
37       } 
38       return $bindata;
39     } 
40 
41     protected function pkcs5_pad ($text) {
42       $blocksize = 16;
43       $pad = $blocksize - (strlen($text) % $blocksize);
44       return $text . str_repeat(chr($pad), $pad);
45     }
46 
47     protected function pkcs5_unpad($text) {
48       $pad = ord($text{strlen($text)-1});
49       if ($pad > strlen($text)) {
50           return false;    
51       }
52       if (strspn($text, chr($pad), strlen($text) - $pad) != $pad) {
53           return false;
54       }
55       return substr($text, 0, -1 * $pad);
56     }
57 }
58 ?>

JAVA类实现

 1 package com.cwilldev.crypt;
 2 
 3 import java.security.NoSuchAlgorithmException;
 4 import javax.crypto.Cipher;
 5 import javax.crypto.NoSuchPaddingException;
 6 import javax.crypto.spec.IvParameterSpec;
 7 import javax.crypto.spec.SecretKeySpec;
 8 
 9 public class ApiCrypter {
10 
11     private String iv              = "fdsfds85435nfdfs"; //根据实际需要更改
12     private String secretkey       = "89432hjfsd891787"; //根据实际需要更改
13     private IvParameterSpec ivspec;
14     private SecretKeySpec keyspec;
15     private Cipher cipher;
16 
17     public ApiCrypter()
18     {
19         ivspec = new IvParameterSpec(iv.getBytes());
20         keyspec = new SecretKeySpec(secretkey.getBytes(), "AES");
21 
22         try {
23             cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
24         } catch (NoSuchAlgorithmException e) {
25             e.printStackTrace();
26         } catch (NoSuchPaddingException e) {
27             e.printStackTrace();
28         }
29     }
30 
31     public byte[] encrypt(String text) throws Exception
32     {
33         if(text == null || text.length() == 0) {
34             throw new Exception("Empty string");
35         }
36         byte[] encrypted = null;
37         try {
38             cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
39             encrypted = cipher.doFinal(text.getBytes("UTF-8"));
40         }
41         catch (Exception e) {
42             throw new Exception("[encrypt] " + e.getMessage());
43         }
44         return encrypted;
45     }
46 
47     public byte[] decrypt(String code) throws Exception
48     {
49         if(code == null || code.length() == 0) {
50             throw new Exception("Empty string");
51         }
52         byte[] decrypted = null;
53         try {
54             cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
55             decrypted = cipher.doFinal(hexToBytes(code));
56         }
57         catch (Exception e) {
58             throw new Exception("[decrypt] " + e.getMessage());
59         }
60         return decrypted;
61     }
62 
63     public static String bytesToHex(byte[] data)
64     {
65         if (data==null) {
66             return null;
67         }
68         int len = data.length;
69         String str = "";
70         for (int i=0; i<len; i++) {
71             if ((data[i]&0xFF)<16) {
72                 str = str + "0" + java.lang.Integer.toHexString(data[i]&0xFF);
73             }
74             else {
75                 str = str + java.lang.Integer.toHexString(data[i]&0xFF);
76             }
77         }
78         return str;
79     }
80 
81     public static byte[] hexToBytes(String str) {
82         if (str==null) {
83             return null;
84         }
85         else if (str.length() < 2) {
86             return null;
87         }
88         else {
89             int len = str.length() / 2;
90             byte[] buffer = new byte[len];
91             for (int i=0; i<len; i++) {
92                 buffer[i] = (byte) Integer.parseInt(str.substring(i*2,i*2+2),16);
93             }
94             return buffer;
95         }
96     }
97 
98 }

PHP加密解密方法:

1 $original_text = 'test';
2 $mdes = new ApiCrypterUtil();
3 //加密
4 $encrypt_text = $mdes->encrypt($original_text);
5 $this->log($encrypt_text, LOG_DEBUG);
6 //解密
7 $this->log($mdes->decrypt($encrypt_text), LOG_DEBUG); 

Java加密解密方法:

1 //加密:
2 ApiCrypter apiCrypter = new ApiCrypter();
3 String originalText = "test";
4 String encryptedText = ApiCrypter.bytesToHex(apiCrypter.encrypt(jsonParams.toString()));
5 //解密:
6 String res = new String(apiCrypter.decrypt(encryptedText), "UTF-8"); 
7 String decryptedText = URLDecoder.decode(res, "UTF-8");

 

posted @ 2013-07-01 14:17  饭遭殃  阅读(989)  评论(0编辑  收藏  举报