zoukankan      html  css  js  c++  java
  • 关于Objective-c和Java下DES加密保持一致的方式

    转载自:http://www.cnblogs.com/janken/archive/2012/04/05/2432930.html

    最近做了一个移动项目,是有服务器和客户端类型的项目,客户端是要登录才行的,登录的密码要用DES加密,服务器是用Java开发的,客户端要同时支持多平台(Android、iOS),在处理iOS的DES加密的时候遇到了一些问题,起初怎么调都调不成和Android端生成的密文相同。最终一个忽然的想法让我找到了问题的所在,现在将代码总结一下,以备自己以后查阅。

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

    按 Ctrl+C 复制代码
    按 Ctrl+C 复制代码

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

    按 Ctrl+C 复制代码
    按 Ctrl+C 复制代码

    以上便是Java端的DES加密方法的全部实现过程。

    我还编写了一个将byte的二进制转换成16进制的方法,以便调试的时候使用打印输出加密后的byte数组的内容,这个方法不是加密的部分,只是为调试而使用的:

    复制代码
     1     /**将二进制转换成16进制 
    2 * @param buf
    3 * @return String
    4 */
    5 public static String parseByte2HexStr(byte buf[]) {
    6 StringBuffer sb = new StringBuffer();
    7 for (int i = 0; i < buf.length; i++) {
    8 String hex = Integer.toHexString(buf[i] & 0xFF);
    9 if (hex.length() == 1) {
    10 hex = '0' + hex;
    11 }
    12 sb.append(hex.toUpperCase());
    13 }
    14 return sb.toString();
    15 }
    复制代码

    下面是Objective-c在iOS上实现的DES加密算法:

    按 Ctrl+C 复制代码
    按 Ctrl+C 复制代码

    下面也是Objective-c的一个二进制转换为16进制的方法,也是为了测试方便查看写的:

    复制代码
     1 +(NSString *) parseByte2HexString:(Byte *) bytes
    2 {
    3 NSMutableString *hexStr = [[NSMutableString alloc]init];
    4 int i = 0;
    5 if(bytes)
    6 {
    7 while (bytes[i] != '')
    8 {
    9 NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
    10 if([hexByte length]==1)
    11 [hexStr appendFormat:@"0%@", hexByte];
    12 else
    13 [hexStr appendFormat:@"%@", hexByte];
    14
    15 i++;
    16 }
    17 }
    18 NSLog(@"bytes 的16进制数为:%@",hexStr);
    19 return hexStr;
    20 }
    21
    22 +(NSString *) parseByteArray2HexString:(Byte[]) bytes
    23 {
    24 NSMutableString *hexStr = [[NSMutableString alloc]init];
    25 int i = 0;
    26 if(bytes)
    27 {
    28 while (bytes[i] != '')
    29 {
    30 NSString *hexByte = [NSString stringWithFormat:@"%x",bytes[i] & 0xff];///16进制数
    31 if([hexByte length]==1)
    32 [hexStr appendFormat:@"0%@", hexByte];
    33 else
    34 [hexStr appendFormat:@"%@", hexByte];
    35
    36 i++;
    37 }
    38 }
    39 NSLog(@"bytes 的16进制数为:%@",hexStr);
    40 return hexStr;
    41 }
    复制代码

    以上的加密方法所在的包是CommonCrypto/CommonCryptor.h。

    以上便实现了Objective-c和Java下在相同的明文和密钥的情况下生成相同明文的算法。

    Base64的算法可以用你们自己写的那个,不一定必须使用我提供的这个。解密的时候还要用Base64进行密文的转换。

    iOS下的Base64算法在后面 。

    JAVA下的解密算法如下:

    按 Ctrl+C 复制代码
    按 Ctrl+C 复制代码

    Base64的decode方法如下:

    按 Ctrl+C 复制代码
    按 Ctrl+C 复制代码

    Objective-c在下的DES解密算法:

    复制代码
     1 +(NSString *)decryptUseDES:(NSString *)cipherText key:(NSString *)key
     2 {
     3     NSString *plaintext = nil;
     4     NSData *cipherdata = [Base64 decode:cipherText];
     5     unsigned char buffer[1024];
     6     memset(buffer, 0, sizeof(char));
     7     size_t numBytesDecrypted = 0;
     8     CCCryptorStatus cryptStatus = CCCrypt(kCCDecrypt, kCCAlgorithmDES,
     9                                           kCCOptionPKCS7Padding,
    10                                           [key UTF8String], kCCKeySizeDES,
    11                                           iv,
    12                                           [cipherdata bytes], [cipherdata length],
    13                                           buffer, 1024,
    14                                           &numBytesDecrypted);
    15     if(cryptStatus == kCCSuccess) {
    16         NSData *plaindata = [NSData dataWithBytes:buffer length:(NSUInteger)numBytesDecrypted];
    17         plaintext = [[NSString alloc]initWithData:plaindata encoding:NSUTF8StringEncoding];
    18     }
    19     return plaintext;
    20 }
    复制代码

    下面是objective-c 实现的Base64工具对象,当然你也可以选择使用google的那个Base64类——GTMBase64(功能很强大),初步测试使用GTMBase64和使用我写的这个Base64效果都是一样的。

    复制代码
      1 static const char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
      2 
      3 @interface Base64()
      4 +(int)char2Int:(char)c;
      5 @end
      6 
      7 @implementation Base64
      8 
      9 +(NSString *)encode:(NSData *)data
     10 {
     11     if (data.length == 0)
     12         return nil;
     13     
     14     char *characters = malloc(data.length * 3 / 2);
     15     
     16     if (characters == NULL)
     17         return nil;
     18     
     19     int end = data.length - 3;
     20     int index = 0;
     21     int charCount = 0;
     22     int n = 0;
     23     
     24     while (index <= end) {
     25         int d = (((int)(((char *)[data bytes])[index]) & 0x0ff) << 16)
     26         | (((int)(((char *)[data bytes])[index + 1]) & 0x0ff) << 8)
     27         | ((int)(((char *)[data bytes])[index + 2]) & 0x0ff);
     28         
     29         characters[charCount++] = encodingTable[(d >> 18) & 63];
     30         characters[charCount++] = encodingTable[(d >> 12) & 63];
     31         characters[charCount++] = encodingTable[(d >> 6) & 63];
     32         characters[charCount++] = encodingTable[d & 63];
     33         
     34         index += 3;
     35         
     36         if(n++ >= 14)
     37         {
     38             n = 0;
     39             characters[charCount++] = ' ';
     40         }
     41     }
     42     
     43     if(index == data.length - 2)
     44     {
     45         int d = (((int)(((char *)[data bytes])[index]) & 0x0ff) << 16)
     46         | (((int)(((char *)[data bytes])[index + 1]) & 255) << 8);
     47         characters[charCount++] = encodingTable[(d >> 18) & 63];
     48         characters[charCount++] = encodingTable[(d >> 12) & 63];
     49         characters[charCount++] = encodingTable[(d >> 6) & 63];
     50         characters[charCount++] = '=';
     51     }
     52     else if(index == data.length - 1)
     53     {
     54         int d = ((int)(((char *)[data bytes])[index]) & 0x0ff) << 16;
     55         characters[charCount++] = encodingTable[(d >> 18) & 63];
     56         characters[charCount++] = encodingTable[(d >> 12) & 63];
     57         characters[charCount++] = '=';
     58         characters[charCount++] = '=';
     59     }
     60     NSString * rtnStr = [[NSString alloc] initWithBytesNoCopy:characters length:charCount encoding:NSUTF8StringEncoding freeWhenDone:YES];
     61     return rtnStr;
     62 
     63 }
     64 
     65 +(NSData *)decode:(NSString *)data
     66 {
     67     if(data == nil || data.length <= 0) {
     68         return nil;
     69     }
     70     NSMutableData *rtnData = [[NSMutableData alloc]init];
     71     int slen = data.length;
     72     int index = 0;
     73     while (true) {
     74         while (index < slen && [data characterAtIndex:index] <= ' ') {
     75             index++;
     76         }
     77         if (index >= slen || index  + 3 >= slen) {
     78             break;
     79         }
     80 
     81         int byte = ([self char2Int:[data characterAtIndex:index]] << 18) + ([self char2Int:[data characterAtIndex:index + 1]] << 12) + ([self char2Int:[data characterAtIndex:index + 2]] << 6) + [self char2Int:[data characterAtIndex:index + 3]];
     82         Byte temp1 = (byte >> 16) & 255;
     83         [rtnData appendBytes:&temp1 length:1];
     84         if([data characterAtIndex:index + 2] == '=') {
     85             break;
     86         }
     87         Byte temp2 = (byte >> 8) & 255;
     88         [rtnData appendBytes:&temp2 length:1];
     89         if([data characterAtIndex:index + 3] == '=') {
     90             break;
     91         }
     92         Byte temp3 = byte & 255;
     93         [rtnData appendBytes:&temp3 length:1];
     94         index += 4;
     95 
     96     }
     97     return rtnData;
     98 }
     99 
    100 +(int)char2Int:(char)c
    101 {
    102     if (c >= 'A' && c <= 'Z') {
    103         return c - 65;
    104     } else if (c >= 'a' && c <= 'z') {
    105         return c - 97 + 26;
    106     } else if (c >= '0' && c <= '9') {
    107         return c - 48 + 26 + 26;
    108     } else {
    109         switch(c) {
    110             case '+':
    111                 return 62;
    112             case '/':
    113                 return 63;
    114             case '=':
    115                 return 0;
    116             default:
    117                 return -1;
    118         }
    119     }
    120 }
    121 
    122 @end
    复制代码

    这个和java端的Base64的是一个算法,只是根据语言的特点不同有少许的改动。

    Java端的测试代码如下:

    1     String plaintext = "abcd";
    2 String ciphertext = DES.encryptDES(plaintext, "20120401");
    3 System.out.println("明文:" + plaintext);
    4 System.out.println("密钥:" + "20120401");
    5 System.out.println("密文:" + ciphertext);
    6 System.out.println("解密后:" + DES.decryptDES(ciphertext, "20120401"));

    输出结果:

    明文:abcd
    密钥:20120401
    密文:W7HR43/usys=
    解密后:abcd


    Objective-c端的测试代码如下:

    1     NSString *plaintext = @"abcd";
    2 NSString *ciphertext = [EncryptUtil encryptUseDES:plaintext key:@"20120401"];
    3 NSLog(@"明文:%@",plaintext);
    4 NSLog(@"秘钥:%@",@"20120401");
    5 NSLog(@"密文:%@",ciphertext);

    输出结果:

    1 2012-04-05 12:00:47.348 TestEncrypt[806:f803] 明文:abcd
    2 2012-04-05 12:00:47.350 TestEncrypt[806:f803] 秘钥:20120401
    3 2012-04-05 12:00:47.350 TestEncrypt[806:f803] 密文:W7HR43/usys=
  • 相关阅读:
    myeclipse包的层数和package的层数不一致
    myeclipse提示:Syntax error on tokens, delete these tokens怎么解决
    智能指针 shared_ptr
    一次读入全部文件到内存中
    条件变量 condition_variable wait_until
    条件变量 condition_variable wait_for
    条件变量 condition_variable wait
    ffmpeg 交叉编译 版本4.0.4
    curl 交叉编译 支持http2和openssl
    nghttp2 交叉编译
  • 原文地址:https://www.cnblogs.com/ruiati/p/3915880.html
Copyright © 2011-2022 走看看