在目标 c 中实现 RC4 加密和 URL 编码



我必须在应用程序中实现 RC4 加密算法以进行 URL 编码。下面列出了示例部件供您参考。

加密前实际值 : 10/28/2013

加密后的期望值:ˆ! ̃·hÇÔÞò

URL 编码后,它应该是:%0C%88%21%98%B7h%C7%D4%DE%F2

使用的密钥是:@"psw"

我已经尝试过,但在加密和URL编码后以这种方式返回价值:

加密后:!·hÇÔÞò

URL 编码后:%0C%C2%88%21%C2%98%C2%B7h%C3%87%C3%94%C3%

9E%C3%B2

我尝试将java代码转换为目标c代码。java代码工作正常,因为目标c不起作用,您可以在上面的结果中看到。

这是Java代码

import java.net.URLEncoder;
public class RC4 {
private char[] key;
private int[] sbox;
private static final int SBOX_LENGTH = 256;
private static final int KEY_MIN_LENGTH = 1;
public static void main(String[] args) {
    try {
        RC4 rc4 = new RC4("psw");
        char[] result = rc4.encrypt("10/28/2013".toCharArray());
        System.out.println("encrypted string:n"
                + new String(toByteArray(result)));
        System.out.println("decrypted string:n"
                + new String(rc4.decrypt(result)));
        System.out.println("decrypted string:n"
                + URLEncoder.encode(new String(toByteArray(result))));
    } catch (InvalidKeyException e) {
        System.err.println(e.getMessage());
    }
}
static byte[] toByteArray(char[] chars) {
    byte[] bytes = new byte[chars.length];
    for (int i = 0; i < chars.length; i++) {
        // bytes[i*2] = (byte) (chars[i] >> 8);
        bytes[i] = (byte) chars[i];
    }
    return bytes;
}
public RC4(String key) throws InvalidKeyException {
    setKey(key);
}
public RC4() {
}
public char[] decrypt(final char[] msg) {
    return encrypt(msg);
}
public char[] encrypt(final char[] msg) {
    sbox = initSBox(key);
    char[] code = new char[msg.length];
    int i = 0;
    int j = 0;
    for (int n = 0; n < msg.length; n++) {
        i = (i + 1) % SBOX_LENGTH;
        j = (j + sbox[i]) % SBOX_LENGTH;
        swap(i, j, sbox);
        int rand = sbox[(sbox[i] + sbox[j]) % SBOX_LENGTH];
        code[n] = (char) (rand ^ (int) msg[n]);
    }
    return code;
}
private int[] initSBox(char[] key) {
    int[] sbox = new int[SBOX_LENGTH];
    int j = 0;
    for (int i = 0; i < SBOX_LENGTH; i++) {
        sbox[i] = i;
    }
    for (int i = 0; i < SBOX_LENGTH; i++) {
        j = (j + sbox[i] + key[i % key.length]) % SBOX_LENGTH;
        swap(i, j, sbox);
    }
    return sbox;
}
private void swap(int i, int j, int[] sbox) {
    int temp = sbox[i];
    sbox[i] = sbox[j];
    sbox[j] = temp;
}
public void setKey(String key) throws InvalidKeyException {
    if (!(key.length() >= KEY_MIN_LENGTH && key.length() < SBOX_LENGTH)) {
        throw new InvalidKeyException("Key length has to be between "
                + KEY_MIN_LENGTH + " and " + (SBOX_LENGTH - 1));
    }
    this.key = key.toCharArray();
}
public class InvalidKeyException extends Exception {
    private static final long serialVersionUID = 1L;
    public InvalidKeyException(String message) {
        super(message);
    }
}
}

其对应的目标 c 代码

-(NSString *)encrypt:(NSString *)string{
[self frameSBox:@"psw"];
unichar code[string.length];
const unichar* buffer = code;
int i = 0;
int j = 0;
for (int n = 0; n < string.length; n++) {
    i = (i + 1) % self.SBOX_LENGTH;
    j = (j + [[self.sBox objectAtIndex:i]integerValue]) % self.SBOX_LENGTH;
    [self swap:i with:j];
    int index=([[self.sBox objectAtIndex:i] integerValue]+[[self.sBox objectAtIndex:j] integerValue]);
    int rand=([[self.sBox objectAtIndex:(index%self.SBOX_LENGTH)] integerValue]);
    code[n]=(rand  ^  (int)[string characterAtIndex:n]);
}
buffer = code;
return  [NSString stringWithCharacters:buffer length:string.length];
}

-(NSArray *)frameSBox:(NSString *)keyValue{

   if (self.sBox == nil) {
    self.sBox=[[NSMutableArray alloc]init];
}
self.SBOX_LENGTH=256;    
int j = 0;
for (int i = 0; i < self.SBOX_LENGTH; i++) {
    [self.sBox addObject:[NSNumber numberWithInteger:i]];
}
for (int i = 0; i < self.SBOX_LENGTH; i++) {
    j = (j + [[self.sBox objectAtIndex:i] integerValue] + [keyValue characterAtIndex:(i % keyValue.length)]) % self.SBOX_LENGTH;
    [self swap:i with:j];
}
return self.sBox;
}

-(void)swap:(int)i with:(int)j{
id tempObj = [self.sBox objectAtIndex:i];
[self.sBox replaceObjectAtIndex:i withObject:[self.sBox objectAtIndex:j]];
[self.sBox replaceObjectAtIndex:j withObject:tempObj];
}
   //I'm calling in a different class by creating the RC4encryptor object 
NSString *unescaped =  [[RC4StringEncryptor encryptor] encrypt:@"10/28/2013"];    
logDebug(@"the value is:%@",unescaped);
NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
        NULL,
        (__bridge CFStringRef) unescaped,
        NULL,
        CFSTR("!*'();:@&=+$,/?%#[]" "),
        kCFStringEncodingUTF8));
    NSLog(@"escapedString: %@",escapedString);

我也试过

#import <CommonCrypto/CommonCryptor.h>
@implementation NSData (RC4)
- (NSData *)RC4EncryptWithKey:(NSString *)key {
char keyPtr[kCCKeySizeMinRC4+1];
bzero(keyPtr, sizeof(keyPtr)); 
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCKeySizeMinRC4;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmRC4, kCCModeRC4,
                                      keyPtr, kCCKeySizeMinRC4,
                                      NULL ,
                                      [self bytes], dataLength,
                                      buffer, bufferSize,
                                      &numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
    return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
- (NSData*) encryptString:(NSString*)plaintext withKey:(NSString*)key {
    return [[plaintext dataUsingEncoding:NSUTF8StringEncoding] RC4EncryptWithKey:key];
}

但是上面的代码对我不起作用。请帮帮我...

不知何故,我修复了您的代码,它可以完美地加密解密。在这里:

@interface RC4Crypt()
@property (nonatomic, strong) NSArray * key;
@property (nonatomic, strong) NSMutableArray * sBox;
@end
@implementation RC4Crypt
static const int SBOX_LENGTH = 256;
static const int KEY_MIN_LENGTH = 1;
-(NSString *)encrypt:(NSString *)string withKey:(NSString *)key{
    self.sBox = [[self frameSBox:key] mutableCopy];
    unichar code[string.length];
    int i = 0;
    int j = 0;
    for (int n = 0; n < string.length; n++) {
        i = (i + 1) % SBOX_LENGTH;
        j = (j + [[self.sBox objectAtIndex:i]integerValue]) % SBOX_LENGTH;
        [self.sBox exchangeObjectAtIndex:i withObjectAtIndex:j];
        int index=([self.sBox[i] integerValue]+[self.sBox[j] integerValue]);
        int rand=([self.sBox[(index%SBOX_LENGTH)] integerValue]);
        code[n]=(rand  ^  (int)[string characterAtIndex:n]);
    }
    const unichar* buffer;
    buffer = code;
    return  [NSString stringWithCharacters:buffer length:string.length];
}
- (NSString*) decrypt:(NSString*)string withKey:(NSString*)key
{
    return [self encrypt:string withKey:key];
}

-(NSArray *)frameSBox:(NSString *)keyValue{
    NSMutableArray *sBox = [[NSMutableArray alloc] initWithCapacity:SBOX_LENGTH];
    int j = 0;
    for (int i = 0; i < SBOX_LENGTH; i++) {
    [sBox addObject:[NSNumber numberWithInteger:i]];
    }
    for (int i = 0; i < SBOX_LENGTH; i++) {
        j = (j + [sBox[i] integerValue] + [keyValue characterAtIndex:(i % keyValue.length)]) % SBOX_LENGTH;
        [sBox exchangeObjectAtIndex:i withObjectAtIndex:j];
    }
    return [NSArray arrayWithArray:sBox];
}
@end

最新更新