手机的短信加解密

 

手机的短信加解密(一)

转载http://www.ophonesdn.com/article/show/133

标签 : 短信 加解密 DES 安全 密码学

 

前言
      随着手机功能的丰富及手机与日常生活的紧密关系,手机信息安全问题越来越成为人们关注的焦点。手机内部信息的泄露、被窃取、遗失或被盗,都会造成重大安全隐患。随着3G时代的来临,手机的高普及率使得手机与个人的生活隐私、商业活动紧密相关,手机的使用安全和隐私安全问题已经突显出来。手机作为一个日益重要的信息载体,如何对其内部及通讯过程中的敏感信息进行有效保护,已经成为亟待解决的问题。
 

一、密码学概述【1】
     使消息保密的技术和科学叫做密码编码学。
 

1.1 密码学基础
          在密码学中,明文用M(消息)或P(明文)表示,它可能是比特流(文本文件、位图、数字化的语音流或数字化的视频图像)。至于涉及到计算机,P是简单地二进制数据(除了这一章节外,这本书本身只涉及二进制数据和计算机密码学)。明文可被传送或存储,无论在哪种情况,M指待加密的消息。密文用C表示,它也是二进制数据,有时和M一样大,有时稍大(通过压缩和加密的结合,C有可能比P小些。然而,单单加密通常达不到这一点)。加密函数E作用于M得到密文C,用数学表示为:
 

E(M)=C.
 

          相反地,解密函数D作用于C产生M
 

D(C)=M.
 

         先加密后再解密消息,原始的明文将恢复出来,下面的等式必须成立:
 

D(E(M))=M
 

1.2 密码学功能
          除了提供机密性外,密码学通常有其它的作用:.
-鉴别:消息的接收者应该能够确认消息的来源;入侵者不可能伪装成他人。
-完整性:消息的接收者应该能够验证在传送过程中消息没有被修改;入侵者不可能用假消息代替合法消息。
-抗抵赖:发送者事后不可能虚假地否认他发送的消息。
 

1.3 算法和密钥
         如果算法的保密性是基于保持算法的秘密,这种算法称为受限制的算法。受限制的算法具有历史意义,但按现在的标准,它们的保密性已远远不够。大的或经常变换的用户组织不能使用它们,因为每有一个用户离开这个组织,其它的用户就必须改换另外不同的算法。如果有人无意暴露了这个秘密,所有人都必须改变他们的算法。
现代密码学用密钥解决了这个问题,密钥用K表示。K可以是很多数值里的任意值。密钥K的可能值的范围叫做密钥空间。加密和解密运算都使用这个密钥(即运算都依赖于密钥,并用K作为下标表示),这样,加/解密函数现在变成:
 

EK(M)=C
DK(C)=M.
 

       这些函数具有下面的特性:
 

DK(EK(M))=M.
 

       有些算法使用不同的加密密钥和解密密钥,也就是说加密密钥K1与相应的解密密钥K2不同,在这种情况下:
 

EK1(M)=C
DK2(C)=M
DK2 (EK1(M))=M
 

       所有这些算法的安全性都基于密钥的安全性;而不是基于算法的细节的安全性。这就意味着算法可以公开,也可以被分析,可以大量生产使用算法的产品,即使偷听者知道你的算法也没有关系;如果他不知道你使用的具体密钥,他就不可能阅读你的消息。
 

1.4 简单异或
       异或在C语言中是“^”操作,或者用数学表达式⊕表示。它是对比特的标准操作:
 

0⊕0 = 0
0⊕1 = 1
1⊕0 = 1
1⊕1 = 0
 

       参照《OPhone手机基础信息与基础业务》(http://www.ophonesdn.com/article/show/102),中的短信发送功能。我们选择0x55(0b01010101)作为密钥,和每一个字节做异或运算,实现加解密。这个算法可以用下列代码来实现,

  1. for(int i=0;i<msg.length();i++) encrymsg[i]=(char) (msg.charAt(i)^'U'); //U的ASCII码为0x55 msg=String.valueOf(encrymsg); sms.sendTextMessage(number, null, msg, pi, null);  
for(int i=0;i<msg.length();i++) encrymsg[i]=(char) (msg.charAt(i)^'U'); //U的ASCII码为0x55 msg=String.valueOf(encrymsg); sms.sendTextMessage(number, null, msg, pi, null);

      在发送端输入明文“helloworld”,短信经过加密如图1所示,变成了不可读的乱码。当我们将密文和0x55再次异或之后,可以获得原始的明文。这就实现了异或加解密。
 

1.5 不安全的异或
          这种方法没有实际的保密性,这类加密可以通过下列两部被轻松破译。(1)用重合码计数法找出密钥长度。(2)按那个长度移动密文,并且和自己异或:这样就消除了密钥,留下明文和移动了密钥长度的明文的异或。


1.6 分组密码介绍
       由于古典密码学(异或属于其中一种)在现在的计算机面前显得不堪一击,现代密码学开始发展。现代密码学中有对称密码、消息摘要函数、公钥密码(用于数字签名)等领域。本文通过循序渐进的办法,介绍加解密在手机信息安全中的应用,首先介绍的是分组密码。
 

       分组密码取用明文的一个区块和钥匙,输出相同大小的密文区块。由于信息通常比单一区块还长,因此有了各种方式将连续的区块编织在一起。 DES和AES是美国联邦政府核定的分组密码标准,本文主要介绍DES算法。【2】
 

        DES对64(bit)位的明文分组M进行操作,M经过一个初始置换IP置换成m0,将m0明文分成左半部分和右半部分m0=(L0,R0),各32位长。然后进行16轮完全相同的运算,这些运算被称为函数f,在运算过程中数据与密匙结合。经过16轮后,左,右半部分合在一起经过一个末置换,完成了加密。
 

      在每一轮中,密匙位移位,然后再从密匙的56位中选出48位。通过一个扩展置换将数据的右半部分扩展成48位,并通过一个异或操作替代成新的32位数据,在将其置换换一次。这四步运算构成了函数f。然后,通过另一个异或运算,函数f的输出与左半部分结合,其结果成为新的右半部分,原来的右半部分成为新的左半部分。将该操作重复16次。流程如图2所示:
 

 

          具体的算法可以参见官方文档:http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf
 

二、手机安全类介绍
         OPhone手机平台上集成了若干信息安全的class,可以用来开发相关的软件。如图3所示。

         本例采用DES算法,对通讯双方的短信进行加解密,其他人如果没有密钥,将不能获知信息内容。在本例中,用到了如下函数库:

 

  1. import java.security.spec.KeySpec;    
  2. /*提供了加密/签名接口      
  3. */  
  4. import javax.crypto.Cipher;     
  5. /*Cipher为加密和解密提供密码功能。它构成了 Java Cryptographic Extension (JCE) 框架的核心。  
  6. 主要方法有:init:用密钥初始化此 Cipher  
  7.             doFinal:按单部分操作加密或解密数据,或者结束一个多部分操作。数据将被加密或解密(具体取决于此 Cipher 的初始化方式)。   
  8. */  
  9. import javax.crypto.SecretKey;  /密钥   
  10. import javax.crypto.SecretKeyFactory;  //密钥工厂   
  11. /*密钥工厂用来将密钥(类型 Key 的不透明加密密钥)转换为密钥规范(底层密钥材料的透明表示形式)。秘密密钥工厂只对秘密(对称)密钥进行操作。密钥工厂为双工模式,即其允许根据给定密钥规范(密钥材料)构建不透明密钥对象,或以适当格式获取密钥对象的底层密钥材料。密钥工厂的参数包括算法 ,加密模式,填充,密码协议  
  12. */  
  13.   
  14. import javax.crypto.spec.DESKeySpec;      
  15. /*实现java.security.spec.KeySpec接口,创建一个 DESKeySpec 对象。  
  16. */  
import java.security.spec.KeySpec; /*提供了加密/签名接口 */ import javax.crypto.Cipher; /*Cipher为加密和解密提供密码功能。它构成了 Java Cryptographic Extension (JCE) 框架的核心。 主要方法有:init:用密钥初始化此 Cipher doFinal:按单部分操作加密或解密数据,或者结束一个多部分操作。数据将被加密或解密(具体取决于此 Cipher 的初始化方式)。 */ import javax.crypto.SecretKey; /密钥 import javax.crypto.SecretKeyFactory; //密钥工厂 /*密钥工厂用来将密钥(类型 Key 的不透明加密密钥)转换为密钥规范(底层密钥材料的透明表示形式)。秘密密钥工厂只对秘密(对称)密钥进行操作。密钥工厂为双工模式,即其允许根据给定密钥规范(密钥材料)构建不透明密钥对象,或以适当格式获取密钥对象的底层密钥材料。密钥工厂的参数包括算法 ,加密模式,填充,密码协议 */ import javax.crypto.spec.DESKeySpec; /*实现java.security.spec.KeySpec接口,创建一个 DESKeySpec 对象。 */

三、实例编写
3.1 xml文件
         为了实现短信发送功能,需要在AndroidManifest.xml中添加permission:

  1. <uses-permission android:name="android.permission.SEND_SMS"></uses-permission>  
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>

         为了实现短信接收功能,除了permission之外,还需要添加receiver:

  1. <receiver android:name="DecryptoSMS" android:enabled="true">   
  2. <intent-filter>   
  3. <action android:name="android.provider.Telephony.SMS_RECEIVED" />   
  4. </intent-filter>   
  5. </receiver>     
  6.   
  7. <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>  
<receiver android:name="DecryptoSMS" android:enabled="true"> <intent-filter> <action android:name="android.provider.Telephony.SMS_RECEIVED" /> </intent-filter> </receiver> <uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>

       软件界面如图4所示:

       运行后界面如图所示。左上角的输入框中填写接收端号码,右上角的输入框中填写密钥。由于DES的分块性质,密钥必须为8字节。SEND按钮提供无加密的短信发送方式。
 

3.2短信生成
         ENCRYPT SEND按钮提供加密短信的发送功能,该按钮关键代码如下:

  1. byte des_key[]= enc_key.getBytes();/*从输入框获取密钥*/  
  2. byte data[] = new byte[64]; /*初始化短信数据*/  
  3. byte tempdata[]= et_text.getText().toString().getBytes();   
  4. /*从输入框获取短信明文*/  
  5. for (int i=0;i<tempdata.length;i++)   
  6.     data[i]=tempdata[i];   
  7. if (tempdata.length <64){ /*复制短信内容至data,不足64位补0*/  
  8.         for (int i=data.length;i<64;i++)   
  9.         data[i]='\0';   
  10.         }   
  11. byte result[] =des_crypt(des_key, data); /*进行加密*/  
byte des_key[]= enc_key.getBytes();/*从输入框获取密钥*/ byte data[] = new byte[64]; /*初始化短信数据*/ byte tempdata[]= et_text.getText().toString().getBytes(); /*从输入框获取短信明文*/ for (int i=0;i<tempdata.length;i++) data[i]=tempdata[i]; if (tempdata.length <64){ /*复制短信内容至data,不足64位补0*/ for (int i=data.length;i<64;i++) data[i]='\0'; } byte result[] =des_crypt(des_key, data); /*进行加密*/


3.3 加密算法
           des_crypt(des_key, data)方法是利用加密密钥和明文数据运算,获得密文的过程。代码如下:

 

  1. static String DES = "DES/ECB/NoPadding";      
  2. /*设置加密方式,包括算法、模式、填充的参数,具体含义参见:http://java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html#AppA*/    
  3.   
  4. public static byte[] des_crypt(byte key[], byte data[]) {     
  5.     try {     
  6.         KeySpec ks = new DESKeySpec(key);  /*新建密钥规范*/  
  7.         SecretKeyFactory kf = SecretKeyFactory.getInstance("DES");    
  8. /* 设置密钥工厂模式为DES,可以设置为AES、DES、DESede、PBEWith等模式  
  9. http://java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html#AppA  
  10. */    
  11.         SecretKey ky = kf.generateSecret(ks);  /*生成密钥*/  
  12.         Cipher c = Cipher.getInstance(DES);  /*设置加密功能*/  
  13.         c.init(Cipher.ENCRYPT_MODE, ky);  /*加密初始化*/  
  14.         return c.doFinal(data);  /*加密运算*/  
  15.     } catch (Exception e) {     
  16.         e.printStackTrace();     
  17.         return null;     
  18.     }     
  19. }    
static String DES = "DES/ECB/NoPadding"; /*设置加密方式,包括算法、模式、填充的参数,具体含义参见:http://java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html#AppA*/ public static byte[] des_crypt(byte key[], byte data[]) { try { KeySpec ks = new DESKeySpec(key); /*新建密钥规范*/ SecretKeyFactory kf = SecretKeyFactory.getInstance("DES"); /* 设置密钥工厂模式为DES,可以设置为AES、DES、DESede、PBEWith等模式 http://java.sun.com/j2se/1.4.2/docs/guide/security/jce/JCERefGuide.html#AppA */ SecretKey ky = kf.generateSecret(ks); /*生成密钥*/ Cipher c = Cipher.getInstance(DES); /*设置加密功能*/ c.init(Cipher.ENCRYPT_MODE, ky); /*加密初始化*/ return c.doFinal(data); /*加密运算*/ } catch (Exception e) { e.printStackTrace(); return null; } }

3.4 数据短信发送
       获得加密结果后,需要将数据发送出去。在之前的短信发送软件中,用的是sendTextMessage方法,该方法只能发送文本数据。短信经过加密之后,会产生手机不能显示的非文本字符,所以我们需要用sendDataMessage方法来发送加密数据:

  1. public final void sendDataMessage (String destinationAddress, String scAddress, short destinationPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent)。  
public final void sendDataMessage (String destinationAddress, String scAddress, short destinationPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent)。

       和sendTextMessage不同之处在于发送数据类型变成了byte,并且增加了目标端口号参数。

  1. SmsManager sms = SmsManager.getDefault();/*建立短信发送管理对象*/  
  2. try {   
  3.   short pt=80/*设置端口号*/  
  4.   PendingIntent pi = PendingIntent.getBroadcast(CryptoSMS.this0new Intent(), 0);   
  5.   sms.sendDataMessage(et_num.getText().toString(), null,pt, result, pi, null); /*填写接收号码、短信数据等参数,并发送短信*/  
  6. Toast.makeText(CryptoSMS.this,"发送成功",Toast.LENGTH_LONG).show ();   
  7. catch (Exception e) {         
  8. Toast.makeText(CryptoSMS.this"发送失败\n"+e.getMessage(),Toast. LENGTH_LONG).show();   
  9. }  
SmsManager sms = SmsManager.getDefault();/*建立短信发送管理对象*/ try { short pt=80; /*设置端口号*/ PendingIntent pi = PendingIntent.getBroadcast(CryptoSMS.this, 0, new Intent(), 0); sms.sendDataMessage(et_num.getText().toString(), null,pt, result, pi, null); /*填写接收号码、短信数据等参数,并发送短信*/ Toast.makeText(CryptoSMS.this,"发送成功",Toast.LENGTH_LONG).show (); } catch (Exception e) { Toast.makeText(CryptoSMS.this, "发送失败\n"+e.getMessage(),Toast. LENGTH_LONG).show(); }

3.5 短信接收
        接收短信采用BroadcastReceiver实现,需要覆盖onReceive方法。在接收到消息后,取出其中的pdu(Protocol Data Unit,协议数据单元)进行解密,获得短信明文。
 

  1. public class DecryptoSMS extends BroadcastReceiver {   
  2. @Override  
  3. public void onReceive(Context context, Intent intent) {    
  4.     Bundle bundle = intent.getExtras();   
  5.     Object pdus[] = (Object[]) bundle.get("pdus");/*获得pdu*/  
  6.     byte[] tempdata = SmsMessage.createFromPdu((byte[]) pdus[0]).getUserData();/*转换为byte格式*/  
  7.     String enc_key= "KEYabcde";     
  8.     byte  des_key[]= enc_key.getBytes();   
  9.     int datalength = (tempdata.length >> 3)*8;    
  10. /*调整密文数据为64bit的倍数*/  
  11.     byte data[] = new byte[datalength];     
  12.     for (int i=0;i<datalength;i++)   
  13.       if (i<64) data[i]=tempdata[i];    
  14. /*为简便起见,设置短信长度不超过64字节*/  
  15.     byte result[] = des_decrypt(des_key,data);     
  16.     String value = new String(result);  /*转换为字符串*/  
  17. Toast.makeText(context,"Received SMS:"+value, Toast.LENGTH_LONG).show();/*提示收到明文短信*/  
  18. }    
public class DecryptoSMS extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); Object pdus[] = (Object[]) bundle.get("pdus");/*获得pdu*/ byte[] tempdata = SmsMessage.createFromPdu((byte[]) pdus[0]).getUserData();/*转换为byte格式*/ String enc_key= "KEYabcde"; byte des_key[]= enc_key.getBytes(); int datalength = (tempdata.length >> 3)*8; /*调整密文数据为64bit的倍数*/ byte data[] = new byte[datalength]; for (int i=0;i<datalength;i++) if (i<64) data[i]=tempdata[i]; /*为简便起见,设置短信长度不超过64字节*/ byte result[] = des_decrypt(des_key,data); String value = new String(result); /*转换为字符串*/ Toast.makeText(context,"Received SMS:"+value, Toast.LENGTH_LONG).show();/*提示收到明文短信*/ }

3.6 短信解密
        解密代码仅仅在cipher的初始化参数有不同,其他完全一样:

  1. public static byte[] des_decrypt(byte key[], byte data[]) {     
  2.     try {     
  3.         KeySpec ks = new DESKeySpec(key);     
  4.         SecretKeyFactory kf = SecretKeyFactory.getInstance("DES");     
  5.         SecretKey ky = kf.generateSecret(ks);     
  6.         Cipher c = Cipher.getInstance(DES);     
  7.         c.init(Cipher.DECRYPT_MODE, ky);     
  8.         return c.doFinal(data);     
  9.     } catch (Exception e) {     
  10.         e.printStackTrace();     
  11.         return null;     
  12.     }     
  13. }  
public static byte[] des_decrypt(byte key[], byte data[]) { try { KeySpec ks = new DESKeySpec(key); SecretKeyFactory kf = SecretKeyFactory.getInstance("DES"); SecretKey ky = kf.generateSecret(ks); Cipher c = Cipher.getInstance(DES); c.init(Cipher.DECRYPT_MODE, ky); return c.doFinal(data); } catch (Exception e) { e.printStackTrace(); return null; } }

四、运行测试
4.1 运行环境

      为了在模拟器上显示短信的收发过程,必须运行两个模拟器。在OMS1.0的平台上,只需在eclipse中run两次就可以了;在OMS1.5平台,启动模拟器必须先创建一个 AVD( Android Virtual Device 虚拟设备 ) 。通过下列命令创建:
 

android create avd --target 1 --name myavd
 

       在工程的Run configuration中(如图5所示)配置该工程选用哪个模拟器,在图6中,可以在指定运行的模拟器AVD上打勾。

4.2 运行结果
          运行软件后,在输入框填写号码、密钥、短信明文,点击ENCRYPT SEND,稍后在另外一个模拟器就能收到密文和明文,如图7所示。可以看到,在收件箱中收到的是乱码,但是在Toast中显示的是解密的结果。


五、总结
        本文介绍了用DES算法加密短信的办法,简单实用。
 

        DES由于其算法简单,可以在几天内被攻破,现在正在逐渐淡出加密舞台。但是,3重DES(triple-DES)还是具有很强的保密性和实用性,其官方文档链接地址如下:http://webstore.ansi.org/RecordDetail.aspx?sku=ANSI+X9.52%3a1998 用户可以通过在DES的基础上略微修改实现。另外,AES(Advanced Encryption Standard)算法的安全性大大超过了DES,当前具有很广的应用。在Cipher的参数中可以选择AES算法来提高安全性,

        但是和三重DES一样,用户需要牺牲运算时间。值得注意的是AES的明文分块是128bit的,密钥是128/192/256bit的,需要在代码中修改byte数组的长度来实现。
 

参考文献
【1】《应用密码学--协议、算法与C源程序》,译者: 吴世忠等,作者: (美)旋奈尔(Schneier,B.)
【2】对称算法(一)DES算法,http://www.infosecurity.org.cn/article/pki/cryptography/23407.html
 

作者介绍
       周轩,就职于浙江移动,OPhone SDN入门版版主,北邮通信硕士,擅长嵌入式系统底层开发,关注移动互联网的发展。
 

(声明:本网的新闻及文章版权均属OPhone SDN网站所有,如需转载请与我们编辑团队联系。任何媒体、网站或个人未经本网书面协议授权,不得进行任何形式的转载。已经取得本网协议授权的媒体、网站,在转载使用时请注明稿件来源。)

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
XML加密解密工具的手机版是一种可以在手机上使用的应用程序,旨在帮助用户对XML文件进行加密解密操作。 XML(可扩展标记语言)是一种常用的数据交换格式,但它的内容通常是以文本形式呈现,并不具备安全性。因此,有时候需要对其中的敏感信息进行加密以保护数据的安全性。 XML加密解密工具手机版提供了一种方便快捷的方式来进行这些操作。用户只需将需要加密的XML文件导入到应用程序中,并设置一个加密密码。应用程序将使用高级加密算法对XML文件进行加密处理,确保加密后的文件无法被未授权的访问者读取。 同样地,用户也可以通过应用程序将加密后的XML文件导入,并输入正确的解密密码。应用程序将使用相同的加密算法和密码进行解密操作,还原XML文件的内容。用户可以随时进行加密解密操作,方便灵活。 XML加密解密工具手机版还提供了其他功能,例如加密解密日志的记录、设置不同加密算法和密码长度等。用户可以根据自己的需求进行设置,以确保加密过程的安全性和稳定性。 总而言之,XML加密解密工具手机版是一款方便实用的应用程序,可以帮助用户对XML文件进行加密解密操作,保护敏感数据的安全性。它为用户提供了高效、安全的加密解密服务,为数据交换提供了更加稳定和可靠的保护。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值