代码改变世界

ios--加密、解密

2015-01-26 16:55  doudo  阅读(282)  评论(0编辑  收藏  举报

一、des加、解密:

1.原理:DES加密 :用CCCrypt函数加密一下,然后用base64编码下,传过去

    DES解密 :把收到的数据根据base64,decode一下,然后再用CCCrypt函数解密,得到原本的数据

2.需要包含:

#import <CommonCrypto/CommonCryptor.h> (CCCrypt所在的文件)

#import "GTMBase64.h"(base64算法)

3.具体实现:

const Byte iv[] = {1,2,3,4,5,6,7,8};

//加密

+(NSString *) encryptUseDES:(NSString *)plainText key:(NSString *)key

{

    NSString *ciphertext = nil;

    NSData *textData = [plainText dataUsingEncoding:NSUTF8StringEncoding];

    NSUInteger dataLength = [textData length];

    unsigned char buffer[1024];

    memset(buffer, 0, sizeof(char));

    size_t numBytesEncrypted = 0;

    CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmDES,

                                          kCCOptionPKCS7Padding,

                                          [key UTF8String], kCCKeySizeDES,

                                          iv,

                                          [textData bytes], dataLength,

                                          buffer, 1024,

                                          &numBytesEncrypted);

    if (cryptStatus == kCCSuccess) {

        NSData *data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesEncrypted];

        ciphertext = [[NSString alloc] initWithData:[GTMBase64 encodeData:data] encoding:NSUTF8StringEncoding];

    }

    return ciphertext;

}

 

//解密

+ (NSString *) decryptUseDES:(NSString*)cipherText key:(NSString*)key

{

    NSData* cipherData = [GTMBase64 decodeString:cipherText];

    unsigned char buffer[1024];

    memset(buffer, 0, sizeof(char));

    size_t numBytesDecrypted = 0;

//    Byte iv[] = {1,2,3,4,5,6,7,8};

    CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt,

                                          kCCAlgorithmDES,

                                          kCCOptionPKCS7Padding,

                                          [key UTF8String],

                                          kCCKeySizeDES,

                                          iv,

                                          [cipherData bytes],

                                          [cipherData length],

                                          buffer,

                                          1024,

                                          &numBytesDecrypted);

    NSString* plainText = nil;

    if (cryptStatus == kCCSuccess) {

        NSData* data = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];

        plainText = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

    }

    return plainText;

}

附:Java端的DES加解密的实现方式,代码如下:

  

public class DES {

private static byte[] iv = { 1, 2, 3, 4, 5, 6, 7, 8 };

public static String encryptDES(String encryptString, String encryptKey)
throws Exception {
IvParameterSpec zeroIv = new IvParameterSpec(iv);
SecretKeySpec key = new SecretKeySpec(encryptKey.getBytes(), "DES");
Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, key, zeroIv);
byte[] encryptedData = cipher.doFinal(encryptString.getBytes());
return Base64.encode(encryptedData);
}
}

上述代码用到了一个Base64的编码类,其代码的实现方式如下:

public class Base64 {
private static final char[] legalChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
.toCharArray();

/**
* data[]进行编码
*
* @param data
* @return
*/
public static String encode(byte[] data) {
int start = 0;
int len = data.length;
StringBuffer buf = new StringBuffer(data.length * 3 / 2);

int end = len - 3;
int i = start;
int n = 0;

while (i <= end) {
int d = ((((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) {
int d = ((((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("=");
} else if (i == start + len - 1) {
int d = (((int) data[i]) & 0x0ff) << 16;

buf.append(legalChars[(d >> 18) & 63]);
buf.append(legalChars[(d >> 12) & 63]);
buf.append("==");
}

return buf.toString();
}

 

二、MD5加密

不可逆

128位或者64位串,byte数字长度就是16和8,一般表示是使用16进制来表示的话,1个byte转换成2个16bit,分别表示高地位,所以生成的字符串是16位或者是32位的,16位其实是从32位中的中间部分抽出来的。

我们所说的密码多少位,是表示多少bit,转换成byte数组的话,就是除以8,但是如果输出16进制的话就是除以4,因为"1111 1111"="FF";

举例来说:256位 byte数组或者NSData的length就是256/8=32 输出16进制就是32*2=64位

JAVA代码:

 

//byte字节转换成16进制的字符串MD5Utils.hexString
public static String hexString(byte[] bytes){
StringBuffer hexValue = new StringBuffer();

for (int i = 0; i < bytes.length; i++) {
int val = ((int) bytes[i]) & 0xff;
if (val < 16)
hexValue.append("0");
hexValue.append(Integer.toHexString(val));
}
return hexValue.toString();
}

 

public byte[] eccrypt(String info) throws NoSuchAlgorithmException{
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] srcBytes = info.getBytes();
//使用srcBytes更新摘要
md5.update(srcBytes);
//完成哈希计算,得到result
byte[] resultBytes = md5.digest();
return resultBytes;
}

public static void main(String args[]) throws NoSuchAlgorithmException{
String msg = "欢迎光临JerryVon的博客";
EncrypMD5 md5 = new EncrypMD5();
byte[] resultBytes = md5.eccrypt(msg);
System.out.println("密文是:" + MD5Utils.hexString(resultBytes));
System.out.println("明文是:" + msg);
}

 

Objective-C代码:(此处一般用32位)

//16位MD5加密方式
- (NSString *)getMd5_16Bit_String:(NSString *)srcString{
//提取32位MD5散列的中间16位
NSString *md5_32Bit_String=[self getMd5_32Bit_String:srcString];
NSString *result = [[md5_32Bit_String substringToIndex:24] substringFromIndex:8];//即9~25位

return result;
}


//32位MD5加密方式
- (NSString *)getMd5_32Bit_String:(NSString *)srcString{
const char *cStr = [srcString UTF8String];
unsigned char digest[CC_MD5_DIGEST_LENGTH];
CC_MD5( cStr, strlen(cStr), digest );
NSMutableString *result = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH * 2];
for(int i = 0; i < CC_MD5_DIGEST_LENGTH; i++)
[result appendFormat:@"%02x", digest[i]];

return result;
}

最后结果是:

明文:欢迎光临JerryVon的博客

密文(32位):3635dc132ba0e49f17534e749b8a99d1
密文(16位):2ba0e49f17534e74

只要比较最后的HEX值,就可以查看原来的串是否相等。

还可以对MD5进行二次加密,也就是对原串进行2次MD5加密