0

我正在尝试使用 openssl 使用 RSA 公钥加密数据。

我有我需要在 Objective-C 中做的事情的 Java 实现。

这是我到目前为止所拥有的:

- (RSA *)rsaFromExponent:(NSString *)exponent modulus:(NSString *)modulus
{
    RSA *rsa_pub = RSA_new();

    const char *N = [modulus UTF8String];
    const char *E = [exponent UTF8String];

    if (!BN_hex2bn(&rsa_pub->n, N))
    {
        // TODO
    }
    printf("N: %s\n", N);
    printf("n: %s\n", BN_bn2dec(rsa_pub->n));

    if (!BN_hex2bn(&rsa_pub->e, E))
    {
        // TODO
    }
    printf("E: %s\n", E);
    printf("e: %s\n", BN_bn2dec(rsa_pub->e));

    return rsa_pub;
}

- (NSString *)cleanString:(NSString *)input
{
    NSString *output = input;
    output = [output stringByReplacingOccurrencesOfString:@"<" withString:@""];
    output = [output stringByReplacingOccurrencesOfString:@">" withString:@""];
    output = [output stringByReplacingOccurrencesOfString:@" " withString:@""];
    return output;
}

// main code
NSString *exponentB64 = @"AQAB";
NSString *modulusB64 = @"AKDbnFpblq7LHfWDfGTR48B34MKaHQosMwVu8cCc6fH2pZ8Ypx/OgzG6VJlKHXeELtlo5tddBSJpwnkEQdvkkmwuOpCkacTTLon6EHqX4WwFW+waqHxmj419SxiDDlo9tsbg7vfFIMpKyGzq1zvTAN3TroW+MxogZfZD3/N6dNTzvBoXe/Ca1e/zVwYXKbiegLMjNwsruz/WvuMiNKTK4U3GEmb0gIODd1shAH10ube8Nrz/e1u9kr25VQ+7kZAFjnkPTp2AvNGYHQt35m1TRMQhTylVwTZqFkHC/jMt7WxuS8q7ftjM828wa1fEWTgWYrdkzmqZSK5CHBYSys/N1Ws=";

// 1. decode base64 (http://projectswithlove.com/projects/NSData_Base64.zip)
NSData *exponent = [NSData dataFromBase64String:exponentB64];
NSData *modulus = [NSData dataFromBase64String:modulusB64];

NSString *exponentHex = [self cleanString:[exponent description]];
NSString *modulusHex = [self cleanString:[modulus description]];

// 2. create RSA public key
RSA *rsa_pub = [self rsaFromExponent:exponentHex modulus:modulusHex];

NSString *user = @"TEST";

// 3. encode base 64
NSData *userData = [user dataUsingEncoding:NSASCIIStringEncoding];
NSString *userB64String = [userData base64EncodedString];

// 4. encrypt
const unsigned char *from = (const unsigned char *)[userB64String cStringUsingEncoding:NSASCIIStringEncoding];
int flen = strlen((const char *)from);
unsigned char *to = (unsigned char *) malloc(RSA_size(rsa_pub));
int padding = RSA_PKCS1_PADDING;
int result = RSA_public_encrypt(flen, from, to, rsa_pub, padding);
if (-1 == result)
{
    NSLog(@"WAT?");
}
else
{
    NSLog(@"from: %s", from); // echo VEVTVA==
    NSLog(@"to: %s", to); // echo something strange with characters like: ~™Ÿû—...
}

// 5. encode base 64
NSString *cipherString = [NSString stringWithCString:(const char *)to
                                            encoding:NSASCIIStringEncoding];
NSData *cipherData = [cipherString dataUsingEncoding:NSASCIIStringEncoding];
NSString *cipherDataB64 = [cipherData base64EncodedString];
NSLog(@"user encrypted b64: %@", cipherDataB64); // echo null :-(

在Java中,我对加密数据进行base64编码没有问题。我确定我做错了什么,但我不知道在哪里,因为这不是我每天都做的事情。
或者,如果您知道使用 Security.framework 等 iOS 框架执行此操作的另一种方法。
提前致谢。

4

1 回答 1

0

别人帮我弄明白了。我不知道为什么,但我假设RSA_public_encrypt函数的输出缓冲区将是一个 ascii 字符串。尽管它也只是文档中所说的字节。这种char *类型经常让我认为它会存储一个字符串(这太错误了,我想这是我最后一次犯这种错误了)。
所以从第5步开始:

// 5. encode base 64
NSData *cipherData = [NSData dataWithBytes:(const void *)to length:result];
NSString *cipherDataB64 = [cipherData base64EncodedString];
NSLog(@"user encrypted b64: %@", cipherDataB64); // now echo the expected value
于 2013-08-27T09:52:18.627 回答