Android客户端与服务器端通过DES加密认证

由于Android应用没有像web开发中的session机制,所以采用PHPSESSID的方式,是没有办法获取客户端登录状态的。

这种情况下,如何在用户登录后,服务器端获取用户登录状态并保持,就必须采用一种“握手”的方式。

每个手机都有自己的IMEI号,那么能不能通过这个标识去做认证呢?

经过试验,答案是可以!

客户端在请求服务器端的时候,请求参数为 IMEI (param 1)及  IMEI&UA (param 2)经过加密的字符串;服务器端对客户端传递的两个参数进行解密,比对两个IMEI值是否相同。如果相同,返回token给客户端,以后每次客户端请求服务器端的时候,都携带该token。这样服务器就可以获取用户登录状态了。

这里,我采用的DES加密的方式,由于PHP和Java的DES加密是有差异的,所以单独进行处理:

java :

  1. import java.security.Key;
  2. import java.security.SecureRandom;
  3. import java.security.spec.AlgorithmParameterSpec;

  4. import javax.crypto.Cipher;
  5. import javax.crypto.SecretKeyFactory;
  6. import javax.crypto.spec.DESKeySpec;
  7. import javax.crypto.spec.IvParameterSpec;


  8. import com.sun.org.apache.xml.internal.security.utils.Base64;

  9. public class Des2
  10. {
  11.     public static final String ALGORITHM_DES = "DES/CBC/PKCS5Padding";

  12.     /**
  13.      * DES算法,加密
  14.      *
  15.      * @param data 待加密字符串
  16.      * @param key  加密私钥,长度不能够小于8位
  17.      * @return 加密后的字节数组,一般结合Base64编码使用
  18.      * @throws CryptException 异常
  19.      */
  20.     public static String encode(String key,String data) throws Exception
  21.     {
  22.         return encode(key, data.getBytes());
  23.     }
  24.     /**
  25.      * DES算法,加密
  26.      *
  27.      * @param data 待加密字符串
  28.      * @param key  加密私钥,长度不能够小于8位
  29.      * @return 加密后的字节数组,一般结合Base64编码使用
  30.      * @throws CryptException 异常
  31.      */
  32.     public static String encode(String key,byte[] data) throws Exception
  33.     {
  34.         try
  35.         {
  36.                     DESKeySpec dks = new DESKeySpec(key.getBytes());
  37.                    
  38.                     SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
  39.             //key的长度不能够小于8位字节
  40.             Key secretKey = keyFactory.generateSecret(dks);
  41.             Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
  42.             IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
  43.             AlgorithmParameterSpec paramSpec = iv;
  44.             cipher.init(Cipher.ENCRYPT_MODE, secretKey,paramSpec);
  45.             
  46.             byte[] bytes = cipher.doFinal(data);
  47.             
  48.             return Base64.encode(bytes);
  49.         } catch (Exception e)
  50.         {
  51.             throw new Exception(e);
  52.         }
  53.     }

  54.     /**
  55.      * DES算法,解密
  56.      *
  57.      * @param data 待解密字符串
  58.      * @param key  解密私钥,长度不能够小于8位
  59.      * @return 解密后的字节数组
  60.      * @throws Exception 异常
  61.      */
  62.     public static byte[] decode(String key,byte[] data) throws Exception
  63.     {
  64.         try
  65.         {
  66.                 SecureRandom sr = new SecureRandom();
  67.                     DESKeySpec dks = new DESKeySpec(key.getBytes());
  68.                     SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
  69.             //key的长度不能够小于8位字节
  70.             Key secretKey = keyFactory.generateSecret(dks);
  71.             Cipher cipher = Cipher.getInstance(ALGORITHM_DES);
  72.             IvParameterSpec iv = new IvParameterSpec("12345678".getBytes());
  73.             AlgorithmParameterSpec paramSpec = iv;
  74.             cipher.init(Cipher.DECRYPT_MODE, secretKey,paramSpec);
  75.             return cipher.doFinal(data);
  76.         } catch (Exception e)
  77.         {
  78.             throw new Exception(e);
  79.         }
  80.     }
  81.    
  82.     /**
  83.      * 获取编码后的值
  84.      * @param key
  85.      * @param data
  86.      * @return
  87.      * @throws Exception
  88.      */
  89.     public static String decodeValue(String key,String data)
  90.     {
  91.             byte[] datas;
  92.             String value = null;
  93.                 try {
  94.                         if(System.getProperty("os.name") != null && (System.getProperty("os.name").equalsIgnoreCase("sunos") || System.getProperty("os.name").equalsIgnoreCase("linux")))
  95.                 {
  96.                             datas = decode(key, Base64.decode(data));
  97.                 }
  98.                     else
  99.                     {
  100.                             datas = decode(key, Base64.decode(data));
  101.                     }
  102.                        
  103.                         value = new String(datas);
  104.                 } catch (Exception e) {
  105.                         value = "";
  106.                 }
  107.             return value;
  108.     }

  109.         /**
  110.         * test
  111.         * @param key : 12345678
  112.         */
  113.     public static void main(String[] args) throws Exception
  114.     {
  115.            
  116.             System.out.println("明:cychai ;密:" + Des2.encode("12345678","cychai"));
  117.     }
  118. }
复制代码
PHP:

  1. class DES
  2. {
  3.         var $key;
  4.         var $iv; //偏移量

  5.         function DES($key, $iv=0)
  6.         {
  7.                 $this->key = $key;
  8.                 if($iv == 0)
  9.                 {
  10.                         $this->iv = $key;
  11.                 }
  12.                 else
  13.                 {
  14.                         $this->iv = $iv;
  15.                 }
  16.         }

  17.         //加密
  18.         function encrypt($str)
  19.         {               
  20.                 $size = mcrypt_get_block_size ( MCRYPT_DES, MCRYPT_MODE_CBC );
  21.                 $str = $this->pkcs5Pad ( $str, $size );
  22.                
  23.                 $data=mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_ENCRYPT, $this->iv);
  24.                 //$data=strtoupper(bin2hex($data)); //返回大写十六进制字符串
  25.                 return base64_encode($data);
  26.         }
  27.    
  28.         //解密
  29.         function decrypt($str)
  30.         {
  31.                 $str = base64_decode ($str);
  32.                 //$strBin = $this->hex2bin( strtolower($str));
  33.                 $str = mcrypt_cbc(MCRYPT_DES, $this->key, $str, MCRYPT_DECRYPT, $this->iv );
  34.                 $str = $this->pkcs5Unpad( $str );
  35.                 return $str;
  36.         }

  37.         function hex2bin($hexData)
  38.         {
  39.                 $binData = "";
  40.                 for($i = 0; $i < strlen ( $hexData ); $i += 2)
  41.                 {
  42.                         $binData .= chr(hexdec(substr($hexData, $i, 2)));
  43.                 }
  44.                 return $binData;
  45.         }

  46.         function pkcs5Pad($text, $blocksize)
  47.         {
  48.                 $pad = $blocksize - (strlen ( $text ) % $blocksize);
  49.                 return $text . str_repeat ( chr ( $pad ), $pad );
  50.         }

  51.         function pkcs5Unpad($text)
  52.         {
  53.                 $pad = ord ( $text {strlen ( $text ) - 1} );
  54.                 if ($pad > strlen ( $text ))
  55.                         return false;
  56.                 if (strspn ( $text, chr ( $pad ), strlen ( $text ) - $pad ) != $pad)
  57.                         return false;
  58.                 return substr ( $text, 0, - 1 * $pad );
  59.         }
  60. }
  61. $str = 'abc';
  62. $key= '12345678';
  63. $crypt = new DES($key);
  64. $mstr = $crypt->encrypt($str);
  65. $str = $crypt->decrypt($mstr);

  66. echo  $str.' <=> '.$mstr;
复制代码
需要注意的是: 加密的key必须为8位或者8的倍数,否则在java加密过程中会报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值