代码加密

移动开发中遇到的最让人纠结的要属Java、Android和iPhone三个平台加解密不一致的问题。因为手机端后台通常是用JAVA开发的Web Service,Android和iPhone客户端调用同样的Web Service接口,为了数据安全考虑,要对数据进行加密。头疼的问题就来了,很难编写出一套加密程序,在3个平台间加解密的结果一致,总不能为Android和iPhone两个客户端各写一套Web Service接口吧?我相信还会有很多朋友为此困惑,在此分享一套3DES加密程序,能够实现Java、Android和iPhone三个平台加解密一致。

首先是JAVA端的加密工具类,它同样适用于Android端,无需任何修改,即可保证Java与Android端的加解密一致,并且中文不会乱码。 
Java代码

  1. package org.liuyq.des3;
  2. import java.security.Key;
  3. import javax.crypto.Cipher;
  4. import javax.crypto.SecretKeyFactory;
  5. import javax.crypto.spec.DESedeKeySpec;
  6. import javax.crypto.spec.IvParameterSpec;
  7. /**
  8. * 3DES加密工具类
  9. */
  10. public class Des3 {
  11. // 密钥
  12. private final static String secretKey = "[email protected]$#365#$";
  13. // 向量
  14. private final static String iv = "01234567";
  15. // 加解密统一使用的编码方式
  16. private final static String encoding = "utf-8";
  17. /**
  18. * 3DES加密
  19. *
  20. * @param plainText 普通文本
  21. * @return
  22. * @throws Exception
  23. */
  24. public static String encode(String plainText) throws Exception {
  25. Key deskey = null;
  26. DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
  27. SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
  28. deskey = keyfactory.generateSecret(spec);
  29. Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
  30. IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
  31. cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
  32. byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
  33. return Base64.encode(encryptData);
  34. }
  35. /**
  36. * 3DES解密
  37. *
  38. * @param encryptText 加密文本
  39. * @return
  40. * @throws Exception
  41. */
  42. public static String decode(String encryptText) throws Exception {
  43. Key deskey = null;
  44. DESedeKeySpec spec = new DESedeKeySpec(secretKey.getBytes());
  45. SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
  46. deskey = keyfactory.generateSecret(spec);
  47. Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
  48. IvParameterSpec ips = new IvParameterSpec(iv.getBytes());
  49. cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
  50. byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));
  51. return new String(decryptData, encoding);
  52. }
  53. }

复制代码

上面的加密工具类会使用到Base64这个类,该类的源代码如下: Java代码

  1. import java.io.ByteArrayOutputStream;
  2. import java.io.IOException;
  3. import java.io.OutputStream;
  4. /**
  5. * Base64编码工具类
  6. */
  7. public class Base64 {
  8. private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
  9. public static String encode(byte[] data) {
  10. int start = 0;
  11. int len = data.length;
  12. StringBuffer buf = new StringBuffer(data.length * 3 / 2);
  13. int end = len - 3;
  14. int i = start;
  15. int n = 0;
  16. while (i <= end) {
  17. int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 0x0ff) << 8) | (((int) data[i + 2]) & 0x0ff);
  18. buf.append(legalChars[(d >> 18) & 63]);
  19. buf.append(legalChars[(d >> 12) & 63]);
  20. buf.append(legalChars[(d >> 6) & 63]);
  21. buf.append(legalChars[d & 63]);
  22. i += 3;
  23. if (n++ >= 14) {
  24. n = 0;
  25. buf.append(" ");
  26. }
  27. }
  28. if (i == start + len - 2) {
  29. int d = ((((int) data[i]) & 0x0ff) << 16) | ((((int) data[i + 1]) & 255) << 8);
  30. buf.append(legalChars[(d >> 18) & 63]);
  31. buf.append(legalChars[(d >> 12) & 63]);
  32. buf.append(legalChars[(d >> 6) & 63]);
  33. buf.append("=");
  34. } else if (i == start + len - 1) {
  35. int d = (((int) data[i]) & 0x0ff) << 16;
  36. buf.append(legalChars[(d >> 18) & 63]);
  37. buf.append(legalChars[(d >> 12) & 63]);
  38. buf.append("==");
  39. }
  40. return buf.toString();
  41. }
  42. private static int decode(char c) {
  43. if (c >= ‘A‘ && c <= ‘Z‘)
  44. return ((int) c) - 65;
  45. else if (c >= ‘a‘ && c <= ‘z‘)
  46. return ((int) c) - 97 + 26;
  47. else if (c >= ‘0‘ && c <= ‘9‘)
  48. return ((int) c) - 48 + 26 + 26;
  49. else
  50. switch (c) {
  51. case ‘+‘:
  52. return 62;
  53. case ‘/‘:
  54. return 63;
  55. case ‘=‘:
  56. return 0;
  57. default:
  58. throw new RuntimeException("unexpected code: " + c);
  59. }
  60. }
  61. /**
  62. * Decodes the given Base64 encoded String to a new byte array. The byte array holding the decoded data is returned.
  63. */
  64. public static byte[] decode(String s) {
  65. ByteArrayOutputStream bos = new ByteArrayOutputStream();
  66. try {
  67. decode(s, bos);
  68. } catch (IOException e) {
  69. throw new RuntimeException();
  70. }
  71. byte[] decodedBytes = bos.toByteArray();
  72. try {
  73. bos.close();
  74. bos = null;
  75. } catch (IOException ex) {
  76. System.err.println("Error while decoding BASE64: " + ex.toString());
  77. }
  78. return decodedBytes;
  79. }
  80. private static void decode(String s, OutputStream os) throws IOException {
  81. int i = 0;
  82. int len = s.length();
  83. while (true) {
  84. while (i < len && s.charAt(i) <= ‘ ‘)
  85. i++;
  86. if (i == len)
  87. break;
  88. int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12) + (decode(s.charAt(i + 2)) << 6) + (decode(s.charAt(i + 3)));
  89. os.write((tri >> 16) & 255);
  90. if (s.charAt(i + 2) == ‘=‘)
  91. break;
  92. os.write((tri >> 8) & 255);
  93. if (s.charAt(i + 3) == ‘=‘)
  94. break;
  95. os.write(tri & 255);
  96. i += 4;
  97. }
  98. }
  99. }

复制代码

接下来是iPhone端的加密程序,当然是用Ojbective-C写的3DES加密程序,源代码如下: 
Java代码

  1. //
  2. //  DES3Util.h
  3. //
  4. #import <Foundation/Foundation.h>
  5. @interface DES3Util : NSObject {
  6. }
  7. // 加密方法
  8. + (NSString*)encrypt:(NSString*)plainText;
  9. // 解密方法
  10. + (NSString*)decrypt:(NSString*)encryptText;
  11. @end

复制代码

Java代码

  1. //
  2. //  DES3Util.m
  3. //
  4. #import "DES3Util.h"
  5. #import <CommonCrypto/CommonCryptor.h>
  6. #import "GTMBase64.h"
  7. #define gkey                        @"[email protected]$#365#$"
  8. #define gIv             @"01234567"
  9. @implementation DES3Util
  10. // 加密方法
  11. + (NSString*)encrypt:(NSString*)plainText {
  12. NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
  13. size_t plainTextBufferSize = [data length];
  14. const void *vplainText = (const void *)[data bytes];
  15. CCCryptorStatus ccStatus;
  16. uint8_t *bufferPtr = NULL;
  17. size_t bufferPtrSize = 0;
  18. size_t movedBytes = 0;
  19. bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
  20. bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
  21. memset((void *)bufferPtr, 0x0, bufferPtrSize);
  22. const void *vkey = (const void *) [gkey UTF8String];
  23. const void *vinitVec = (const void *) [gIv UTF8String];
  24. ccStatus = CCCrypt(kCCEncrypt,
  25. kCCAlgorithm3DES,
  26. kCCOptionPKCS7Padding,
  27. vkey,
  28. kCCKeySize3DES,
  29. vinitVec,
  30. vplainText,
  31. plainTextBufferSize,
  32. (void *)bufferPtr,
  33. bufferPtrSize,
  34. &movedBytes);
  35. NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
  36. NSString *result = [GTMBase64 stringByEncodingData:myData];
  37. return result;
  38. }
  39. // 解密方法
  40. + (NSString*)decrypt:(NSString*)encryptText {
  41. NSData *encryptData = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];
  42. size_t plainTextBufferSize = [encryptData length];
  43. const void *vplainText = [encryptData bytes];
  44. CCCryptorStatus ccStatus;
  45. uint8_t *bufferPtr = NULL;
  46. size_t bufferPtrSize = 0;
  47. size_t movedBytes = 0;
  48. bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
  49. bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
  50. memset((void *)bufferPtr, 0x0, bufferPtrSize);
  51. const void *vkey = (const void *) [gkey UTF8String];
  52. const void *vinitVec = (const void *) [gIv UTF8String];
  53. ccStatus = CCCrypt(kCCDecrypt,
  54. kCCAlgorithm3DES,
  55. kCCOptionPKCS7Padding,
  56. vkey,
  57. kCCKeySize3DES,
  58. vinitVec,
  59. vplainText,
  60. plainTextBufferSize,
  61. (void *)bufferPtr,
  62. bufferPtrSize,
  63. &movedBytes);
  64. NSString *result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr
  65. length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding] autorelease];
  66. return result;
  67. }
  68. @end

复制代码

iPhone端的加密工具类中引入了“GTMBase64.h”,这是iOS平台的Base64编码工具类,就不在这里贴出相关代码了,需要的百度一下就能找到。

这样,JAVA,Android和iPhone三个平台的加密不一致问题就可以解决了。其实,对此问题,还有一种更好的实现方式,那就是用C语言写一套加密程序,这样在iOS平台是可以直接使用C程序的,而在Java和Android端通过JNI去调用C语言编写的加密方法,这样也可以实现3个平台调用同一套加密程序。

时间: 2024-10-13 07:21:49

代码加密的相关文章

iOS代码加密的几种方式

众所周知的是大部分iOS代码一般不会做加密加固,因为iOS APP一般是通过AppStore发布的,而且苹果的系统难以攻破,所以在iOS里做代码加固一般是一件出力不讨好的事情.万事皆有例外,不管iOS.adr还是js,加密的目的是为了代码的安全性,虽然现在开源畅行,但是不管个人开发者还是大厂皆有保护代码安全的需求,所以iOS代码加固有了生存的土壤.下面简单介绍下iOS代码加密的几种方式. iOS代码加密的几种方式 1.字符串加密 字符串会暴露APP的很多关键信息,攻击者可以根据从界面获取的字符串

iOS代码加密常用加密方式

在今天的面试中,被问到了iOS是采用什么进行加密解密操作的,我的回答是这样的:AES,MD5,Base 64,然后是对这几种加密算法进行了一下简单的介绍和概述和几种算法之间的不同点和优缺点.然而,收到的回答是:这些都不是iOS的加密!我顿时就无语了,这不就是iOS加密所用到的方法么?然后向面试官请教了一下:MD5是一种摘要....什么叫加密呢?加密是客户端对数据加密和服务器端采用秘钥对数据进行解密处理,为了数据的安全考虑.要说加密应该是RSA.幸亏之前有了解过RSA,只是了解的不是很彻底和清楚.

把代码加密成乱码?不如让代码隐身吧!

先声明,娱乐向,至于有没有实用价值就不知道了...轻喷哈. 今天在网上乱逛的时候看到了陈浩大牛的这篇博客:http://coolshell.cn/articles/1142.html 感觉里面说的WhiteSpace语言很有意思.维基百科: http://zh.wikipedia.org/wiki/Whitespace 一般的编程语言都会忽略空白字符,而WhiteSpace却只识别空白字符,优点竟然是“不能把代码打印带走”... 虽然不知道有没有人真的用这个语言做项目开发,但是这给了我们一个思路

一种采用COM交互机制的VBA加密办法,适用于大部分VBA代码加密

原始出处:http://www.cnblogs.com/Charltsing/p/EncryptVBACode.html VBA代码加密是个老生常谈的问题,自从本人的VBA Dumper发布之后,在Office层面上做任何加密都已经失去了意义.所以,很多人开始转战VB封装或者升级到VSTO,Delphi等其他语言.但是,对于广大的VBAer来说,重新学一门语言带来的麻烦要远远超过开发VBA程序所带来的收益.所以,是否能有一种办法在不改变VBA代码的情况下,将VBA代码脱离office进行加密呢?

cocos2dx lua 代码加密

代码加密使用luajit加密 具体文件路径就是: ....\frameworks\cocos2d-x\external\lua\luajit\src\src 加密的工具windows bat批处理: 代码如下: @echo off if exist out rd /s /q out mkdir out :input cls set input=: set /p input= ÍÏÈëÒª±àÒëµÄluaÎļþ¼Ð£º set "input=%input:"=%" if &

JavaScript js如何代码加密绑定域名

(function(){for(var c=location.host,a="",b=0;b<c.length;b++)a+=c[b].charCodeAt(0);if("119119119461161011151164699111109"!=a)throw new URIError("\u968f\u4fbf\u5199\u70b9\u5565\u54c7\u3002\u3002");})(); 把上边这段代码加入不让其他域名加载的js文

关于网页代码加密解密保护,保障页面安全

[-调取原代码的方法-]  1:右键 - 查看原文件  2:查看 - 原文件  3:文件 - 另存为  4:IE缓存  5:还可以通过代码提取  教程代码:  <SCRIPT>  function add()  {  var ress=document.forms[0].it315zhangxx.value  window.location="view-source:"+ress;  }  </SCRIPT>  <p>在网页源代码查看器中输入要查看网

对Java代码加密的两种方式,防止反编译

使用Virbox Protector对Java项目加密有两种方式,一种是对War包加密,一种是对Jar包加密.Virbox Protector支持这两种文件格式加密,可以加密用于解析class文件的java.exe,并且可以实现项目源码绑定制定设备,防止部署到客户服务器的项目被整体拷贝. 两种加密方式 War 包加密 当你的项目在没有完成竣工的时候,不适合使用 war 文件,因为你的类会由于调试之类的经常改,这样来回删除.创建 war 文件很不爽,最好是你的项目已经完成了,不改了,那么就打个 w

Lua代码加密,防止代码反编译

加密目的: 在游戏开发中,脚本作为一种资源文件,就像图片视频一样,被引擎所引用.如果不对脚本进行加密,不怀好意的人轻松解压出脚本文件,给你瞬间复制一个游戏出来.在程序发布前一般会对脚本进行加密,防止代码泄漏. 加密工具: Virbox Protector DS Protector 优点: 便捷,一键加壳,无需编写代码. 安全,混淆.虚拟化.碎片代码.反黑.定制SDK等最新加密安全技术. 快速,5分钟完成整个程序加壳,专注软件开发. 灵活,云锁.软锁.硬件锁三种许可形式,可满足联网或离线场景,云和