iOS RC4加密的实现,要注意加密后生成字符串的步骤,有些要求是base64加密后输出,有些要求是字节数组转16进制字符串输出,所以要特别注意。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
|
// rc4加密 - (NSString *)rc4Encode:(NSString *)aInput key:(NSString *)aKey { NSMutableArray *iS = [[NSMutableArray alloc] initWithCapacity:256]; NSMutableArray *iK = [[NSMutableArray alloc] initWithCapacity:256]; for (int i= 0; i<256; i++) { [iS addObject:[NSNumber numberWithInt:i]]; } int j=1; for (short i=0; i<256; i++) { UniChar c = [aKey characterAtIndex:i%aKey.length]; [iK addObject:[NSNumber numberWithChar:c]]; } j=0; for (int i=0; i<256; i++) { int is = [[iS objectAtIndex:i] intValue]; UniChar ik = (UniChar)[[iK objectAtIndex:i] charValue]; j = (j + is + ik)%256; NSNumber *temp = [iS objectAtIndex:i]; [iS replaceObjectAtIndex:i withObject:[iS objectAtIndex:j]]; [iS replaceObjectAtIndex:j withObject:temp]; } int i=0; j=0; Byte byteBuffer[aInput.length]; for (short x=0; x<[aInput length]; x++) { i = (i+1)%256; int is = [[iS objectAtIndex:i] intValue]; j = (j+is)%256; int is_i = [[iS objectAtIndex:i] intValue]; int is_j = [[iS objectAtIndex:j] intValue]; int t = (is_i+is_j) % 256; // 这里需要注意,原版这里是先取值,再交换位置,但是有问题,应该先交换位置,再取值!!! [iS exchangeObjectAtIndex:i withObjectAtIndex:j]; int iY = [[iS objectAtIndex:t] intValue]; UniChar ch = (UniChar)[aInput characterAtIndex:x]; UniChar ch_y = ch^iY; byteBuffer[x] = ch_y; } // 字节数组转16进制字符串输出 NSString *resultString = [self stringFromByte:byteBuffer length:aInput.length]; // NSData *adata = [[NSData alloc] initWithBytes:byteBuffer length:aInput.length]; // NSString *string = [adata base64EncodedStringWithOptions:0]; // 以base64的加密结果输出 return resultString; }
//rc4解密 - (NSString *)rc4Decode:(NSString *)data key:(NSString*)secret{ // 如果是16进制字符串 NSData *raw = [self ByteDataFromString:data]; // 如果是base64加密后字符串 // NSData *raw = [[NSData alloc] initWithBase64EncodedString:data options:0]; int cipherLength = (int)raw.length; UInt8 *cipher = malloc(cipherLength); [raw getBytes:cipher length:cipherLength]; NSData *kData = [secret dataUsingEncoding:NSUTF8StringEncoding]; int keyLength = (int)kData.length; UInt8 *kBytes = malloc(kData.length); [kData getBytes:kBytes length:kData.length]; UInt8 *decipher = malloc(cipherLength + 1); UInt8 iS[256]; UInt8 iK[256]; int i; for (i = 0; i < 256; i++){ iS[i] = i; iK[i] = kBytes[i % keyLength]; } int j = 0; for (i = 0; i < 256; i++){ int is = iS[i]; int ik = iK[i]; j = (j + is + ik)% 256; UInt8 temp = iS[i]; iS[i] = iS[j]; iS[j] = temp; } int q = 0; int p = 0; for (int x = 0; x < cipherLength; x++){ q = (q + 1)% 256; p = (p + iS[q])% 256; int k = iS[p]; iS[p] = iS[q]; iS[q] = k; k = iS[(iS[q] + iS[p])% 256]; decipher[x] = cipher[x] ^ k; } free(kBytes); decipher[cipherLength] = '\0'; return @((char *)decipher); }
// 字节数组转 - (NSString *)stringFromByte:(Byte *)byteBuffer length:(NSInteger)length { NSMutableString *hexString = [[NSMutableString alloc] init]; for (int i = 0; i < length; i++) { [hexString appendString:[NSString stringWithFormat:@"%0.2hhx", byteBuffer[i]]]; } return [hexString uppercaseString]; }
- (NSData *)ByteDataFromString:(NSString *)targetStr { NSInteger len = [targetStr length] / 2; // Target length unsigned char *buf = malloc(len); unsigned char *whole_byte = buf; char byte_chars[3] = {'\0','\0','\0'};
int i; for (i=0; i < [targetStr length] / 2; i++) { byte_chars[0] = [targetStr characterAtIndex:i*2]; byte_chars[1] = [targetStr characterAtIndex:i*2+1]; *whole_byte = strtol(byte_chars, NULL, 16); whole_byte++; }
NSData *data = [NSData dataWithBytes:buf length:len]; free( buf ); return data; }
|
参考
iOS,objectC,RC4加密解密方法
iOS 二进制数组转成16进制字符串