1、找到文件
下载地址:https://yunpan.cn/ckxIZwyppN3Pb (提取码:23cd)
2、导入文件
由于这两个文件不不支持ARC,因此应该为GTMBase64.m 和 DES3Util.m添加编译标记-fno-objc-arc进行局部ARC禁止。
3、加密后打印出来结果
4、修改明文
这其中遇到的最让人纠结的要属Java、Android和iPhone三个平台加解密不一致的问题。因为手机端后台通常是用JAVA开发的Web Service,Android和iPhone客户端调用同样的Web Service接口,为了数据安全考虑,要对数据进行加密。头疼的问题就来了,很难编写出一套加密程序,在3个平台间加解密的结果一致,总不能为Android和iPhone两个客户端各写一套Web Service接口吧?我相信还会有很多朋友为此困惑,在此分享一套3DES加密程序,能够实现Java、Android和iPhone三个平台加解密一致。
首先是JAVA端的加密工具类,它同样适用于Android端,无需任何修改,即可保证Java与Android端的加解密一致,并且中文不会乱码。
packageorg.liuyq.des3;
importjava.security.Key;
importjavax.crypto.Cipher;
importjavax.crypto.SecretKeyFactory;
importjavax.crypto.spec.DESedeKeySpec;
importjavax.crypto.spec.IvParameterSpec;
/**
* 3DES加密工具类
*
* @author liufeng
* @date 2012-10-11
*/
publicclassDes3 {
// 密钥
privatefinalstaticString secretKey ="liuyunqiang@lx100$#365#$";
// 向量
privatefinalstaticString iv ="01234567";
// 加解密统一使用的编码方式
privatefinalstaticString encoding ="utf-8";
/**
* 3DES加密
*
* @param plainText 普通文本
* @return
* @throws Exception
*/
publicstaticString encode(String plainText)throwsException {
Key deskey =null;
DESedeKeySpec spec =newDESedeKeySpec(secretKey.getBytes());
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
IvParameterSpec ips =newIvParameterSpec(iv.getBytes());
cipher.init(Cipher.ENCRYPT_MODE, deskey, ips);
byte[] encryptData = cipher.doFinal(plainText.getBytes(encoding));
returnBase64.encode(encryptData);
}
/**
* 3DES解密
*
* @param encryptText 加密文本
* @return
* @throws Exception
*/
publicstaticString decode(String encryptText)throwsException {
Key deskey =null;
DESedeKeySpec spec =newDESedeKeySpec(secretKey.getBytes());
SecretKeyFactory keyfactory = SecretKeyFactory.getInstance("desede");
deskey = keyfactory.generateSecret(spec);
Cipher cipher = Cipher.getInstance("desede/CBC/PKCS5Padding");
IvParameterSpec ips =newIvParameterSpec(iv.getBytes());
cipher.init(Cipher.DECRYPT_MODE, deskey, ips);
byte[] decryptData = cipher.doFinal(Base64.decode(encryptText));
returnnewString(decryptData, encoding);
}
}
上面的加密工具类会使用到Base64这个类,该类的源代码如下:
packageorg.liuyq.des3;
importjava.io.ByteArrayOutputStream;
importjava.io.IOException;
importjava.io.OutputStream;
/**
* Base64编码工具类
*
* @author liufeng
* @date 2012-10-11
*/
publicclassBase64 {
privatestaticfinalchar[] legalChars ="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
publicstaticString encode(byte[] data) {
intstart =0;
intlen = data.length;
StringBuffer buf =newStringBuffer(data.length *3/2);
intend = len -3;
inti = start;
intn =0;
while(i <= end) {
intd = ((((int) data[i]) &0x0ff) <<16) | ((((int) data[i +1]) &0x0ff) <<8) | (((int) data[i +2]) &0x0ff);
buf.append(legalChars[(d >>18) &63]);
buf.append(legalChars[(d >>12) &63]);
buf.append(legalChars[(d >>6) &63]);
buf.append(legalChars[d &63]);
i +=3;
if(n++ >=14) {
n =0;
buf.append(" ");
}
}
if(i == start + len -2) {
intd = ((((int) data[i]) &0x0ff) <<16) | ((((int) data[i +1]) &255) <<8);
buf.append(legalChars[(d >>18) &63]);
buf.append(legalChars[(d >>12) &63]);
buf.append(legalChars[(d >>6) &63]);
buf.append("=");
}elseif(i == start + len -1) {
intd = (((int) data[i]) &0x0ff) <<16;
buf.append(legalChars[(d >>18) &63]);
buf.append(legalChars[(d >>12) &63]);
buf.append("==");
}
returnbuf.toString();
}
privatestaticintdecode(charc) {
if(c >='A'&& c <='Z')
return((int) c) -65;
elseif(c >='a'&& c <='z')
return((int) c) -97+26;
elseif(c >='0'&& c <='9')
return((int) c) -48+26+26;
else
switch(c) {
case'+':
return62;
case'/':
return63;
case'=':
return0;
default:
thrownewRuntimeException("unexpected code: "+ c);
}
}
/**
* Decodes the given Base64 encoded String to a new byte array. The byte array holding the decoded data is returned.
*/
publicstaticbyte[] decode(String s) {
ByteArrayOutputStream bos =newByteArrayOutputStream();
try{
decode(s, bos);
}catch(IOException e) {
thrownewRuntimeException();
}
byte[] decodedBytes = bos.toByteArray();
try{
bos.close();
bos =null;
}catch(IOException ex) {
System.err.println("Error while decoding BASE64: "+ ex.toString());
}
returndecodedBytes;
}
privatestaticvoiddecode(String s, OutputStream os)throwsIOException {
inti =0;
intlen = s.length();
while(true) {
while(i < len && s.charAt(i) <=' ')
i++;
if(i == len)
break;
inttri = (decode(s.charAt(i)) <<18) + (decode(s.charAt(i +1)) <<12) + (decode(s.charAt(i +2)) <<6) + (decode(s.charAt(i +3)));
os.write((tri >>16) &255);
if(s.charAt(i +2) =='=')
break;
os.write((tri >>8) &255);
if(s.charAt(i +3) =='=')
break;
os.write(tri &255);
i +=4;
}
}
}
接下来是iPhone端的加密程序,当然是用Ojbective-C写的3DES加密程序,源代码如下:
//
// DES3Util.h
// lx100-gz
//
// Copyright 2012http://blog.csdn.net/lyq8479. All rights reserved.
//
#import
@interface DES3Util : NSObject {
}
// 加密方法
+ (NSString*)encrypt:(NSString*)plainText;
// 解密方法
+ (NSString*)decrypt:(NSString*)encryptText;
@end
[plain]view plaincopy
//
// DES3Util.m
// lx100-gz
//
// Created by 柳峰 on 12-9-17.
// Copyright 2012http://blog.csdn.net/lyq8479. All rights reserved.
//
#import "DES3Util.h"
#import
#import "GTMBase64.h"
#define gkey @"liuyunqiang@lx100$#365#$"
#define gIv @"01234567"
@implementation DES3Util
// 加密方法
+ (NSString*)encrypt:(NSString*)plainText {
NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
size_t plainTextBufferSize = [data length];
const void *vplainText = (const void *)[data bytes];
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
const void *vkey = (const void *) [gkey UTF8String];
const void *vinitVec = (const void *) [gIv UTF8String];
ccStatus = CCCrypt(kCCEncrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
vkey,
kCCKeySize3DES,
vinitVec,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
NSString *result = [GTMBase64 stringByEncodingData:myData];
return result;
}
// 解密方法
+ (NSString*)decrypt:(NSString*)encryptText {
NSData *encryptData = [GTMBase64 decodeData:[encryptText dataUsingEncoding:NSUTF8StringEncoding]];
size_t plainTextBufferSize = [encryptData length];
const void *vplainText = [encryptData bytes];
CCCryptorStatus ccStatus;
uint8_t *bufferPtr = NULL;
size_t bufferPtrSize = 0;
size_t movedBytes = 0;
bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
memset((void *)bufferPtr, 0x0, bufferPtrSize);
const void *vkey = (const void *) [gkey UTF8String];
const void *vinitVec = (const void *) [gIv UTF8String];
ccStatus = CCCrypt(kCCDecrypt,
kCCAlgorithm3DES,
kCCOptionPKCS7Padding,
vkey,
kCCKeySize3DES,
vinitVec,
vplainText,
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes);
NSString *result = [[[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr
length:(NSUInteger)movedBytes] encoding:NSUTF8StringEncoding] autorelease];
return result;
}
@end
iPhone端的加密工具类中引入了“GTMBase64.h”,这是iOS平台的Base64编码工具类,就不在这里贴出相关代码了,需要的百度一下就能找到,实在找不到就回复留言给我。
好了,赶紧试一下吧,JAVA,Android和iPhone三个平台的加密不一致问题是不是解决了呢?其实,对此问题,还有一种更好的实现方式,那就是用C语言写一套加密程序,这样在iOS平台是可以直接使用C程序的,而在Java和Android端通过JNI去调用C语言编写的加密方法,这是不是就实现了3个平台调用同一套加密程序呢?
感谢柳峰技术博客:http://blog.csdn.net/lyq8479/article/details/8062867