obj c和java_PKCS1-padding / RSA加密ios objc和java之间的区别

我正在为ios和Android开发应用程序。我对加密任务相对来说比较陌生,在过去的3天里,由于无法运行RSA加密,所以我一直在抨击我的头部。

两个客户端都从java服务器接收公钥。在Android中我有(显然,因为它几乎与服务器端的代码相同)没有问题,但是ios部分似乎根本不兼容。我想用公钥来加密一小段数据(aes key),这就是我在Java中如何做到的:

try {

String publickey = "MCwwDQYJKoZIhvcNAQEBBQADGwAwGAIRAK+dBpbOKw+1VKMWoFxjU6UCAwEAAQ==";

byte[] bArr = Crypto.base64Decode(publicKey, false);

KeyFactory keyFactory = KeyFactory.getInstance("RSA", "BC");

EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKey);

PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);

Cipher cipher = Cipher.getInstance("RSA/NONE/PKCS1Padding", "BC");

cipher.init(1,publicKey);

int cipherBlockSize = cipher.getBlockSize();

ByteArrayOutputStream bArrOut = new ByteArrayOutputStream();

bArrOut.flush();

int pos = 0;

Log.i("ContentBufferLength", contentBuffer.length+"");

while (true) {

if (cipherBlockSize > contentBuffer.length - pos) {

cipherBlockSize = contentBuffer.length - pos;

}

Log.i("CipherBlockSize", cipherBlockSize+"");

byte[] tmp = cipher.doFinal(contentBuffer, pos, cipherBlockSize);

bArrOut.write(tmp);

pos += cipherBlockSize;

if (contentBuffer.length <= pos) {

break;

}

}

bArrOut.flush();

encryptedBuffer = bArrOut.toByteArray();

bArrOut.close();

} catch (Exception ex) {

throw ex;

}

// Log.i("Encrypted Buffer Length", encryptedBuffer.length+"");

return encryptedBuffer;这是我的(不正常工作)ios代码,从这里借用:

http://blog.wingsofhermes.org/?p=75和苹果加密练习。

-(NSString* )encryptWithPublicKey:(NSString*)key input:(NSString*) input {

const size_t BUFFER_SIZE = 16;

const size_t CIPHER_BUFFER_SIZE = 16;

//const uint32_t PADDING = kSecPaddingNone;

const uint32_t PADDING = kSecPaddingPKCS1;

static const UInt8 publicKeyIdentifier[] = "de.irgendwas.app";

NSData *publicTag;

publicTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)];

NSMutableDictionary *publicKey2 = [[NSMutableDictionary alloc] init];

[publicKey2 setObject:kSecClassKey forKey:kSecClass];

[publicKey2 setObject:kSecAttrKeyTypeRSA forKey:kSecAttrKeyType];

[publicKey2 setObject:publicTag forKey:kSecAttrApplicationTag];

SecItemDelete((CFDictionaryRef)publicKey2);

NSData *strippedPublicKeyData = [NSData dataFromBase64String:key];

unsigned char * bytes = (unsigned char *)[strippedPublicKeyData bytes];

size_t bytesLen = [strippedPublicKeyData length];

size_t i = 0;

if (bytes[i++] != 0x30)

[Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

/* Skip size bytes */

if (bytes[i] > 0x80)

i += bytes[i] - 0x80 + 1;

else

i++;

if (i >= bytesLen)

[Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

if (bytes[i] != 0x30)

[Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

/* Skip OID */

i += 15;

if (i >= bytesLen - 2)

[Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

if (bytes[i++] != 0x03)

[Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

/* Skip length and null */

if (bytes[i] > 0x80)

i += bytes[i] - 0x80 + 1;

else

i++;

if (i >= bytesLen)

[Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

if (bytes[i++] != 0x00)

[Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

if (i >= bytesLen)

[Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

strippedPublicKeyData = [NSData dataWithBytes:&bytes[i] length:bytesLen - i];

DLog(@"X.509 Formatted Public Key bytes:\n%@",[strippedPublicKeyData description]);

if (strippedPublicKeyData == nil)

[Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

CFTypeRef persistKey = nil;

[publicKey2 setObject:strippedPublicKeyData forKey:kSecValueData];

[publicKey2 setObject: (kSecAttrKeyClassPublic) forKey:kSecAttrKeyClass];

[publicKey2 setObject:[NSNumber numberWithBool:YES] forKey:kSecReturnPersistentRef];

OSStatus secStatus = SecItemAdd((CFDictionaryRef)publicKey2, &persistKey);

if (persistKey != nil) CFRelease(persistKey);

if ((secStatus != noErr) && (secStatus != errSecDuplicateItem))

[Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

SecKeyRef keyRef = nil;

[publicKey2 removeObjectForKey:kSecValueData];

[publicKey2 removeObjectForKey:kSecReturnPersistentRef];

[publicKey2 setObject:[NSNumber numberWithBool:YES] forKey:kSecReturnRef];

[publicKey2 setObject: kSecAttrKeyTypeRSA forKey:kSecAttrKeyType];

SecItemCopyMatching((CFDictionaryRef)publicKey2,(CFTypeRef *)&keyRef);

if (!keyRef)

[Exception raise:FAILURE function:__PRETTY_FUNCTION__ line:__LINE__ description:@"Could not set public key."];

uint8_t *plainBuffer;

uint8_t *cipherBuffer;

uint8_t *decryptedBuffer;

const char inputString[] = "1234";

int len = strlen(inputString);

// TODO: this is a hack since i know inputString length will be less than BUFFER_SIZE

if (len > BUFFER_SIZE) len = BUFFER_SIZE-1;

plainBuffer = (uint8_t *)calloc(BUFFER_SIZE, sizeof(uint8_t));

cipherBuffer = (uint8_t *)calloc(CIPHER_BUFFER_SIZE, sizeof(uint8_t));

decryptedBuffer = (uint8_t *)calloc(BUFFER_SIZE, sizeof(uint8_t));

strncpy( (char *)plainBuffer, inputString, len);

size_t plainBufferSize = strlen((char *)plainBuffer);

size_t cipherBufferSize = CIPHER_BUFFER_SIZE;

NSLog(@"SecKeyGetBlockSize() public = %lu", SecKeyGetBlockSize(keyRef));

// Error handling

// Encrypt using the public.

OSStatus status = noErr;

status = SecKeyEncrypt(keyRef,

PADDING,

plainBuffer,

plainBufferSize,

&cipherBuffer[0],

&cipherBufferSize

);

NSLog(@"encryption result code: %ld (size: %lu)", status, cipherBufferSize);

return [[[NSString stringWithFormat:@"%s",cipherBuffer] dataUsingEncoding:NSUTF8StringEncoding] base64EncodedString];

}出于测试目的和当下的简单性,我试图仅加密长度为4个字节的输入。这应该足够小以适应一个街区。公钥导入和加密过程似乎可行,但与android方法相比,我总是可以获得更长的输出。

我到目前为止遇到的唯一区别是,SecKeyGetBlockSize returns 16和java cipher.blocksize返回5.我认为其他11个字节是为pkcs1填充保留的,但是如何强制ios/objc中的相同行为?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值