C语言的EDS与RSA算法,在使用RSA加密的iPhone上解密C内容时遇到问题

到目前为止,我已经花了两天时间来研究我所能利用的所有资源,所以这是最后的办法。

我有一个X509证书,它的公钥存储在iPhone的钥匙链中(目前仅限模拟器)。在ASP.NET方面,我已经在证书存储中获得了带有私钥的证书。当我在iPhone上加密一个字符串并在服务器上解密它时,我得到一个

CryptographicException

“坏数据。”我尝试了

Array.Reverse

建议在

RSACryptoServiceProvider

一页在一个长卷上,但没有帮助。

我比较了两边的base-64字符串,它们是相等的。我比较了解码后的原始字节数组,它们也是相等的。如果我使用公钥在服务器上加密,字节数组与iPhone的版本不同,并且很容易使用私钥进行解密。原始纯文本字符串是115个字符,因此它在2048位密钥的256字节限制范围内。

这是iPhone加密方法(相当多来自

CryptoExercise sample app

wrapSymmetricKey

方法:

+ (NSData *)encrypt:(NSString *)plainText usingKey:(SecKeyRef)key error:(NSError **)err

{

size_t cipherBufferSize = SecKeyGetBlockSize(key);

uint8_t *cipherBuffer = NULL;

cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));

memset((void *)cipherBuffer, 0x0, cipherBufferSize);

NSData *plainTextBytes = [plainText dataUsingEncoding:NSUTF8StringEncoding];

OSStatus status = SecKeyEncrypt(key, kSecPaddingNone,

(const uint8_t *)[plainTextBytes bytes],

[plainTextBytes length], cipherBuffer,

&cipherBufferSize);

if (status == noErr)

{

NSData *encryptedBytes = [[[NSData alloc]

initWithBytes:(const void *)cipherBuffer

length:cipherBufferSize] autorelease];

if (cipherBuffer)

{

free(cipherBuffer);

}

NSLog(@"Encrypted text (%d bytes): %@",

[encryptedBytes length], [encryptedBytes description]);

return encryptedBytes;

}

else

{

*err = [NSError errorWithDomain:@"errorDomain" code:status userInfo:nil];

NSLog(@"encrypt:usingKey: Error: %d", status);

return nil;

}

}

下面是服务器端C解密方法:

private string Decrypt(string cipherText)

{

if (clientCert == null)

{

// Get certificate

var store = new X509Store(StoreName.My, StoreLocation.LocalMachine);

store.Open(OpenFlags.ReadOnly);

foreach (var certificate in store.Certificates)

{

if (certificate.GetNameInfo(X509NameType.SimpleName, false) == CERT)

{

clientCert = certificate;

break;

}

}

}

using (var rsa = (RSACryptoServiceProvider)clientCert.PrivateKey)

{

try

{

var encryptedBytes = Convert.FromBase64String(cipherText);

var decryptedBytes = rsa.Decrypt(encryptedBytes, false);

var plaintext = Encoding.UTF8.GetString(decryptedBytes);

return plaintext;

}

catch (CryptographicException e)

{

throw(new ApplicationException("Unable to decrypt payload.", e));

}

}

}

我怀疑平台之间存在一些编码问题。

我知道一个是大尾数,另一个是小尾数,但我不知道该说哪一个或如何克服差异。

Mac OS X、Windows和iPhone都是小endian,所以这不是问题所在。

新理论:如果将OAEP填充布尔值设置为false,则默认为pkcs 1 1.5填充。

SecKey

只有

SecPadding

定义

PKCS1

,

PKCS1MD2

,

PKCS1MD5

PKCS1SHA1

. 也许是微软的PKC 11.5!=apple的pkcs1,因此填充会影响加密的二进制输出。我试着用

kSecPaddingPKCS1

fOAEP

设置为

false

但它仍然不起作用。

显然地,

ksecpaddingpkcs1

equivalent

到PKCSα1,1.5。回到理论的画板上…

其他新尝试的理论:

iPhone(.cer文件)上的证书与服务器(.pfx文件)上的pkcs 12捆绑包不完全相同,因此它无法工作。在不同的证书存储和服务器加密字符串中安装了.cer文件,回退得很好;

转换成base-64和向服务器发布的行为导致了同一类往返旅行中不存在的奇怪现象,所以我首先尝试了一些URLENCoding/decoding,然后从iPhone发布原始二进制文件,验证它是相等的,得到了相同的坏数据;

我的原始字符串是125个字节,所以我认为它可能是以UTF-8(长截图)截断的,所以我将其裁剪为44个字节的字符串,但没有结果;

回顾一下系统,密码库确保我使用了一个合适的类,并发现了“rsapkcs1keyExchangeDeformatter”,在新的前景中变得兴高采烈,当它的行为完全相同时,我感到沮丧。

成功!

事实证明,我在iPhone模拟器上的钥匙链上有点粗糙,可以这么说,它把水弄脏了。我删除了钥匙链数据库

~/Library/Application Support/iPhone Simulator/User/Library/Keychains/keychain-2-debug.db

使它被重新创造,并且工作得很好。谢谢你的帮助。据估计,这是一件简单但不明显的事情。(我学到了两件事:1)从模拟器中卸载应用程序并不能清除其钥匙链条目;2)定期全新启动。)

注意:keychain文件的常规路径取决于iOS版本:

~/library/application support/iphone simulator/[版本]/library/keychains/keychain-2-debug.db

例如。,

~/library/application support/iphone模拟器/4.3/library/keychains/keychain-2-debug.db

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值