我试图加密IOS中的字符串,然后在C#中解密它。
我只使用C#对字符串进行加密和解密,但IOS端似乎不正确。
在C#中,我使用它解密字符串:
private static RSACryptoServiceProvider _rsa;
private const int PROVIDER_RSA_FULL = 1;
private const string CONTAINER_NAME = "KeyContainer";
private const string PROVIDER_NAME = "Microsoft Strong Cryptographic Provider";
private static void _AssignParameter()
{
CspParameters cspParams;
cspParams = new CspParameters(PROVIDER_RSA_FULL, PROVIDER_NAME, CONTAINER_NAME);
cspParams.Flags = CspProviderFlags.UseMachineKeyStore;
CryptoKeyAccessRule rule = new CryptoKeyAccessRule("everyone", CryptoKeyRights.FullControl, AccessControlType.Allow);
cspParams.CryptoKeySecurity = new CryptoKeySecurity();
cspParams.CryptoKeySecurity.SetAccessRule(rule);
_rsa = new RSACryptoServiceProvider(cspParams);
_rsa.PersistKeyInCsp = false;
}
private static void decrypt(byte[] data, byte[] PrivateKey)
{
_AssignParameter();
_rsa.ImportCspBlob(PrivateKey);
_rsa.Decrypt(data, false);
}上面的C#代码只是一个片段,而不是完整的代码。
这看起来很简单,这就是我在IOS上使用的,
//get nsdata from mod and exp
NSString *mod = publicKeyObjects[0];
NSData *pubKeyModData= [mod dataUsingEncoding:NSUTF8StringEncoding]; //172 bytes
NSString *exp = publicKeyObjects[1];
NSData *pubKeyExpData= [exp dataUsingEncoding:NSUTF8StringEncoding];
//create nsdata key with mod and exp
NSMutableArray *publicKeyArray = [[NSMutableArray alloc] init];
[publicKeyArray addObject:pubKeyModData];
[publicKeyArray addObject:pubKeyExpData];
NSData *publicKeyData = [publicKeyArray berData];
//add the key to the keychain and create a ref
NSData* peerTag = [@"KeyContainer" dataUsingEncoding:NSUTF8StringEncoding];
NSMutableDictionary *publicKey = [[NSMutableDictionary alloc] init];
[publicKey setObject:(__bridge id) kSecClassKey forKey:(__bridge id)kSecClass];
[publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
[publicKey setObject:peerTag forKey:(__bridge id)kSecAttrApplicationTag];
SecItemDelete((__bridge CFDictionaryRef)publicKey);
CFTypeRef persistKey = nil;
// Add persistent version of the key to system keychain
[publicKey setObject:publicKeyData forKey:(__bridge id)kSecValueData];
[publicKey setObject:(__bridge id) kSecAttrKeyClassPublic forKey:(__bridge id)kSecAttrKeyClass];
[publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnPersistentRef];
OSStatus secStatus = SecItemAdd((__bridge CFDictionaryRef)publicKey, &persistKey);
if (persistKey != nil)
CFRelease(persistKey);
// Now fetch the SecKeyRef version of the key
SecKeyRef keyRef = nil;
[publicKey removeObjectForKey:(__bridge id)kSecValueData];
[publicKey removeObjectForKey:(__bridge id)kSecReturnPersistentRef];
[publicKey setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef];
[publicKey setObject:(__bridge id) kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType];
secStatus = SecItemCopyMatching((__bridge CFDictionaryRef)publicKey,(CFTypeRef *)&keyRef);
NSData* stringData = [@"string to encrypt" dataUsingEncoding:NSUTF8StringEncoding];
NSData* encryptedString = [self encrypt:passwordData usingKey:keyRef];
-(NSData *)encrypt:(NSData *)Bytes usingKey:(SecKeyRef)key
{
size_t cipherBufferSize = SecKeyGetBlockSize(key); //returns 172
uint8_t *cipherBuffer = NULL;
cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
memset((void *)cipherBuffer, 0x0, cipherBufferSize);
OSStatus status = SecKeyEncrypt(key, kSecPaddingNone,
(const uint8_t *)[Bytes bytes],
[Bytes length], cipherBuffer,
&cipherBufferSize);
if (status == noErr)
{
NSData *encryptedBytes = [[NSData alloc]
initWithBytes:(const void *)cipherBuffer
length:cipherBufferSize];
if (cipherBuffer)
{
free(cipherBuffer);
}
NSLog(@"Encrypted text (%d bytes): %@", [encryptedBytes length], [encryptedBytes description]);
return encryptedBytes;
}
else
{
NSLog(@"encrypt:usingKey: Error: %d", (int)status);
return nil;
}
}因此,一旦我试图解密C#代码上的数据,就会得到:
The data to be decrypted exceeds the maximum for this modulus of 128 bytes.
我在googled上搜索了这个错误,并看到它与键大小有关,但是在i导入IOS模数之后的键大小是172字节。
但是我只是用_rsa.ToXmlString(false);导出了公钥
编辑
我想我修正了自己的错误,
//get nsdata from mod and exp
NSString *mod = publicKeyObjects[0];
NSData *pubKeyModData= [mod dataUsingEncoding:NSUTF8StringEncoding];
NSString *exp = publicKeyObjects[1];
NSData *pubKeyExpData= [exp dataUsingEncoding:NSUTF8StringEncoding];这是将base64字符串直接与utf8进行转换,它应该使用:
NSData *pubKeyModData = [[NSData alloc] initWithBase64EncodedString:mod options:0];
NSData *pubKeyExpData = [[NSData alloc] initWithBase64EncodedString:exp options:0];现在我得到了另一个错误Bad Data
有人能给我指个正确的方向吗?我也为所有的密码道歉。我只是不知道问题出在哪里。
发布于 2014-03-17 13:03:48
回答了我自己的问题
//get nsdata from mod and exp
NSString *mod = publicKeyObjects[0];
NSData *pubKeyModData= [mod dataUsingEncoding:NSUTF8StringEncoding];
NSString *exp = publicKeyObjects[1];
NSData *pubKeyExpData= [exp dataUsingEncoding:NSUTF8StringEncoding];变成这样:
//get nsdata from mod and exp
NSString *mod = publicKeyObjects[0];
NSData *pubKeyModData = [[NSData alloc] initWithBase64EncodedString:mod options:0];
NSString *exp = publicKeyObjects[1];
NSData *pubKeyExpData = [[NSData alloc] initWithBase64EncodedString:exp options:0];然后这个
OSStatus status = SecKeyEncrypt(key, kSecPaddingNone,
(const uint8_t *)[Bytes bytes],
[Bytes length], cipherBuffer,
&cipherBufferSize);变成:
OSStatus status = SecKeyEncrypt(key, kSecPaddingPKCS1,
(const uint8_t *)[Bytes bytes],
[Bytes length], cipherBuffer,
&cipherBufferSize);简单的配置修复。
https://stackoverflow.com/questions/22450098
复制相似问题