在 C# 中解密使用 RSA 在 iPhone 上加密的内容时遇到问题

2024-01-09

到目前为止,我已经花了两天时间研究这个问题,并梳理了我可以使用的所有资源,所以这是最后的手段。

我有一个 X509 证书,其公钥已存储在 iPhone 的钥匙串中(此时仅限模拟器)。在 ASP.NET 方面,我已在证书存储区中使用私钥获取了证书。当我在 iPhone 上加密一个字符串并在服务器上解密它时,我得到一个CryptographicException“糟糕的数据。”我尝试过Array.Reverse建议在RSACryptoServiceProvider http://msdn.microsoft.com/en-us/library/system.security.cryptography.rsacryptoserviceprovider.aspx页面上的长镜头,但它没有帮助。

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

这是 iPhone 的加密方法(几乎是逐字逐句地来自CryptoExercise 示例应用程序 http://developer.apple.com/iphone/library/samplecode/CryptoExercise/listing15.html's 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都是小端字节序,所以这不是问题。

新理论:如果将 OAEP 填充布尔值设置为 false,则默认为 PKCS#1 1.5 填充。SecKey只有SecPadding的定义PKCS1, PKCS1MD2, PKCS1MD5, and PKCS1SHA1。也许 Microsoft 的 PKCS#1 1.5 != Apple 的 PKCS1,因此填充会影响加密的二进制输出。我尝试使用kSecPaddingPKCS1fOAEP set to false但它仍然不起作用。 显然,kSecPaddingPKCS1 is 相等的 http://lists.apple.com/archives/Apple-cdsa/2009/Jul/msg00027.html到 PKCS#1 1.5。回到理论的绘图板......

其他新尝试的理论:

  1. iPhone 上的证书(.cer 文件)与服务器上的 PKCS#12 捆绑包(.pfx 文件)不完全相同,因此它永远无法工作。在不同的证书存储中安装了 .cer 文件,并且服务器加密的字符串往返就好了;
  2. 转换为 base-64 以及 POST 到服务器的行为会导致同一类往返中不存在的奇怪情况,因此我首先尝试了一些 URLEncoding/Decoding,然后从 iPhone 发布原始二进制文件,验证它是否相等,并得到相同的错误数据;
  3. 我的原始字符串是 125 字节,所以我认为它可能会在 UTF-8 中被截断(长镜头),所以我将其裁剪为 44 字节字符串,但没有结果;
  4. 回顾 System.Cryptography 库,以确保我使用了合适的类,并发现了“RSAPKCS1KeyExchangeDeformatter”,对新的前景感到高兴,但当它的行为完全相同时感到沮丧。

Success!

事实证明,我的 iPhone 模拟器钥匙串里有一些东西,可以这么说,把水搅浑了。我删除了钥匙串数据库~/Library/Application Support/iPhone Simulator/User/Library/Keychains/keychain-2-debug.db使其被重新创建并且运行良好。感谢您的所有帮助。我认为这可能是一些简单但不明显的事情。 (我学到了两件事:1)从模拟器中卸载应用程序不会清除其钥匙串条目,2)定期重新启动。)

注意:钥匙串文件的通用路径取决于 iOS 版本: 〜/库/应用程序支持/iPhone模拟器/[版本]/Library/Keychains/keychain-2-debug.db 例如。, 〜/库/应用程序支持/iPhone模拟器/4.3/Library/Keychains/keychain-2-debug.db


嗯...第一步(正如您所说的那样)是使用 iPhone 和 C# 实现使用相同的初始化向量来加密相同的消息。您应该得到相同的输出。你说你没有,所以有问题。

这意味着:

  • iPhone 的 RSA 实现不正确。
  • RSA 的 .NET 实现不正确。
  • 密钥文件不同(或解释不同)。

我建议前两种可能性不大,但可能性很小。

您声明:“在不同的证书存储中安装了 .cer 文件,并且服务器加密的字符串往返得很好”...这并不能证明任何事情:所有这些证明的是,给定一组特定的随机数字,您可以成功加密/解密一个平台。您不能保证两个平台都看到相同的随机数集。

所以我建议你把它降到尽可能低的水平。检查两个平台上加密的直接(字节数组)输入和输出。如果使用完全相同的(二进制)输入,您没有得到相同的输出,那么您就会遇到平台问题。我认为这不太可能,所以我猜你会发现 IV 的解释不同。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 C# 中解密使用 RSA 在 iPhone 上加密的内容时遇到问题 的相关文章

  • 使用 C# 登录《我的世界》

    我正在尝试为自己和一些朋友创建一个简单的自定义 Minecraft 启动器 我不需要启动 Minecraft 的代码 只需要登录的实际代码行 例如 据我所知 您过去可以使用 string netResponse httpGET https
  • UIWebView 中的 PDF

    我正在创建一个杂志应用程序 我在 UIWebView 中显示杂志的每一页 不过 Web 视图不会用 PDF 填满屏幕 它周围有一个边界 我怎样才能全屏显示它 我还没有使用 UIWebView 尝试过此操作 但您也许可以执行类似的操作来以编程
  • 当一组凭据下的计划任务启动的进程在另一组凭据下运行另一个程序时,Windows 是否有限制

    所以我有一个简单的例子 其中我有应用程序 A 它对用户 X 本地管理员 有一些硬编码的凭据 然后它使用硬编码的绝对路径启动带有这些凭据的应用程序 B A 和 B 以及 dotnet 控制台应用程序 但是它们不与控制台交互 只是将信息写入文件
  • 如何减少典型 iPhone 应用程序的启动时间?

    需要明确的是 这是一个普通的 iPhone 应用程序 而不是游戏 我在网上读过几次 一些开发人员提到他们正在努力改进 减少应用程序的启动时间 但从来没有提供任何关于如何做到这一点的良好背景信息 那么问题很简单 如何减少 iPhone 应用程
  • 使用 LINQ to SQL 时避免连接超时的最佳实践

    我需要知道在 net 应用程序中使用 LINQ to SQL 时避免连接超时的最佳实践 特别是在返回时IQueryable
  • 在Linux中,找不到框架“.NETFramework,Version=v4.5”的参考程序集

    我已经设置了 Visual studio 来在我的 Ubuntu 机器上编译 C 代码 我将工作区 我的代码加载到 VS 我可以看到以下错误 The reference assemblies for framework NETFramewo
  • 告诉 Nancy 将枚举序列化为字符串

    Nancy 默认情况下在生成 JSON 响应时将枚举序列化为整数 我需要将枚举序列化为字符串 有一种方法可以通过创建来自定义 Nancy 的 JSON 序列化JavaScript 原始转换器 https github com NancyFx
  • IQueryable 单元或集成测试

    我有一个 Web api 并且公开了一个端点 如下所示 api 假期 name name 这是 Web api 的控制器 get 方法 public IQueryable
  • GMSMapView 中的倒多边形

    我必须在我的 iPhone 项目中使用 Google 地图 并且我正在使用 GMSPolygon 来绘制多边形 但是如何填充地图上除多边形内部之外的所有位置 就像下图一样 谢谢 我玩过你的问题 主要思想是用多边形填充整个地球 然后为您的特定
  • 为什么这个二维指针表示法有效,而另一个则无效[重复]

    这个问题在这里已经有答案了 这里我编写了一段代码来打印 3x3 矩阵的对角线值之和 这里我必须将矩阵传递给函数 矩阵被传递给指针数组 代码可以工作 但问题是我必须编写参数的方式如下 int mat 3 以下导致程序崩溃 int mat 3
  • 为什么我的单选按钮不起作用?

    我正在 Visual C 2005 中开发 MFC 对话框应用程序 我的单选按钮是 m Small m Medium 和 m Large 它们都没有在我的 m Summary 编辑框中显示应有的内容 可能出什么问题了 这是我的代码 Pizz
  • 在mysql连接字符串中添加应用程序名称/程序名称[关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 我正在寻找一种解决方案 在连接字符串中添加应用程序名称或程序名称 以便它在 MySQL Workbench 中的 客户端连接 下可见 SQL
  • C++ int 前面加 0 会改变整个值

    我有一个非常奇怪的问题 如果我像这样声明一个 int int time 0110 然后将其显示到控制台返回的值为72 但是当我删除前面的 0 时int time 110 然后控制台显示110正如预期的那样 我想知道两件事 首先 为什么它在
  • WPF DataGridTemplateColumn 组合框更新所有行

    我有这个 XAML 它从 ItemSource 是枚举的组合框中选择一个值 我使用的教程是 http www c sharpcorner com uploadfile dpatra combobox in datagrid in wpf h
  • 在屏幕上获取字符

    我浏览了 NCurses 函数列表 似乎找不到返回已打印在屏幕上的字符的函数 每个字符单元格中存储的字符是否有可访问的值 如果没有的话Windows终端有类似的功能吗 我想用它来替换屏幕上某个值的所有字符 例如 所有a s 具有不同的特征
  • WebBrowser.Print() 等待完成。 。网

    我在 VB NET 中使用 WebBrowser 控件并调用 Print 方法 我正在使用 PDF 打印机进行打印 当调用 Print 时 它不会立即启动 它会等到完成整个子或块的运行代码 我需要确保我正在打印的文件也完整并继续处理该文件
  • 实体框架中的“it”是什么

    如果以前有人问过这个问题 请原谅我 但我的任何搜索中都没有出现 它 我有两个数据库表 Person 和 Employee 对每个类型的表进行建模 例如 Employee is a Person 在我的 edmx 设计器中 我定义了一个实体
  • 可访问性不一致:参数类型的可访问性低于方法

    我试图在两个表单之间传递一个对象 基本上是对当前登录用户的引用 目前 我在登录表单中有一些类似的内容 private ACTInterface oActInterface public void button1 Click object s
  • GCC 的“-Wl,option”和“-Xlinker option”语法之间有区别吗?

    我一直在查看一些配置文件 并且看到它们都被使用 尽管在不同的体系结构上 如果您在 Linux 机器上使用 GCC 将选项传递给链接器的两种语法之间有区别吗 据我所知 阅读 GCC 手册时 他们的解释几乎相同 From man gcc Xli
  • 如何在 iOS 中注册自定义文件类型

    我目前正在创建一个应用程序 我想让用户在其中备份他们的文件 plist m4a 我压缩文件并将扩展名更改为自定义扩展名 专门针对我的应用程序 例如 MyBackup 然后 用户可以通过电子邮件或 iTunes 文件共享进行导出 我已经阅读过

随机推荐

  • 如何从 xcode 获取自己的应用程序版本?

    我想知道是否有办法在将其放入 xCode 中的 Summary 选项卡后 在代码中获取自己的应用程序版本 一种方法似乎是搜索Info plist for CFBundleVersion关键 但是还有其他更简单 更方便的方法吗 您可以在主包中
  • VB.NET LINQ 按多列分组

    我有以下 LINQ 代码 该代码有语法错误 但我不知道如何修复它 Dim query From row In mainDatatable AsEnumerable the syntax Error is in the following l
  • 保持当前页面呈现,直到加载下一页

    我有一个基于 WebView loadUrl http www example com http www example com 当用户单击 URL 时 默认行为是立即显示空白页面 等待页面加载 然后显示此页面 我设法显示启动屏幕来代替空白
  • POSIX TIMER - 有多个计时器

    我试图在我的系统中有两个计时器用于两个不同的目的 但我不明白为什么它不起作用 有人可以帮助我吗 另外 处理程序代码是否应该是最低限度的 以便任务本身不会干扰滴答声 我还可以定义单独的处理程序吗 include
  • 如何在客户注册表中添加地址字段?

    我使用的是magento 1 6 我想在客户注册表上显示地址字段 我从 register phtml 中删除了以下几行 但它不起作用 所以我该怎么做 如果您使用的是 magento 1 6 或更高版本 并且只需在customers form
  • One-hot 编码多级列数据

    我有以下数据框 其中包含有关不同主题的特征的记录 ID Feature 1 A 1 B 2 A 1 A 3 B 3 B 1 C 2 C 3 D 我想获得另一个 聚合的 数据帧 其中每一行代表一个特定主题 并且有所有单热编码功能的详尽列表 I
  • Cordova 应用程序可以编译,但在运行时崩溃。如何获取错误报告?

    我有一个 Cordova 应用程序 编译时没有错误 然而 当我将应用程序加载到我的 Android 设备上时 它在启动时立即崩溃 当我不知道错误是什么时 我很难进行调试 问题 有没有办法从这次崩溃中获取错误报告 我通常使用 Chrome 来
  • 在哪里以及如何安装 ArcPy for Python 2.7?

    我检查过http www lfd uci edu gohlke pythonlibs http www lfd uci edu gohlke pythonlibs http help arcgis com en arcgisdesktop
  • 如何在 for 循环中追加 pandas 数据框中的行? [复制]

    这个问题在这里已经有答案了 我有以下 for 循环 for i in links data urllib2 urlopen str i read data json loads data data pd DataFrame data ite
  • 如何在 Vim 中进行类似于“grep -w”的全字搜索

    我如何进行全字搜索 例如grep w在 Vim 中 它只返回所寻找的字符串是整个单词而不是较大单词的一部分的行 grep w 仅选择包含构成整个单词的匹配项的行 这可以在 Vim 中完成吗
  • 数据结构:此类练习中 pop、push、dequeue、enqueue 的解释

    我正在努力熟悉这 4 个概念 所以如果我们有一个数组 15 34 23 32 15 5 我们的业务包括 pop push 30 enqueue 40 dequeue 100 pop 只会删除第一个数字 即 15 对吧 如果是 pop 20
  • 如何同时静默对 Rails 控制器操作的调用

    我已经弄清楚如何通过将操作方法 内的所有内容包装在 logger silence 块中来使操作的内容静音 但是 我仍然收到对日志文件中显示的操作的调用 I E Processing DashboardController update fo
  • 如何从 获取持续时间,如 int milli 和 float 秒?

    我正在尝试使用 chrono 库来设置计时器和持续时间 我希望能够拥有一个Duration frameStart 从应用程序启动 和一个Duration frameDelta 帧之间的时间 我需要能够得到frameDelta持续时间为毫秒和
  • 在 Xamarin.iOS 中创建可扩展的表格视图?

    我正在尝试使用创建可扩展的表格视图Xamarin iOS具有手风琴类型的功能 例如 最初会有一些行 点击任何行 单元格将扩展到表视图中的其他一些行 Thanks 嘿 我制作了一个可扩展表格视图的示例here https github com
  • 我可以使用 OpenCL 分配设备内存并在 CUDA 中使用指向内存的指针吗?

    假设我使用 OpenCL 来管理内存 以便 GPU CPU 之间的内存管理使用相同的代码 但我的计算使用优化的 CUDA 和 CPU 代码 不是 OpenCL 我仍然可以使用 OpenCL 设备内存指针并将它们传递给 CUDA 函数 内核吗
  • 学习正确使用VBO

    因此 我一直在尝试自学使用 VBO 以提高 OpenGL 项目的性能并学习比固定功能渲染更高级的东西 但我还没有找到太多像样的教程 到目前为止我发现的最好的是宋浩的教程 http www songho ca opengl gl vbo ht
  • 修改 beforeFind 回调中所需的 Containable 字段?

    在我的 CakePHP 1 2 5 应用程序中 我有一个Profile模型属于User模型 用户模型有一个username字段 并且当执行find 在 Profile 模型上 我希望始终自动检索User username也 我认为修改我的配
  • Angular2 中组件属性变化的可观察

    当在 Angular 2 中创建一个通过 Input 具有输入属性的组件时 如何从对该属性 Input 所做的更改中获取可观察值 不要与用户表单输入混淆 export class ExampleComponent implement OnC
  • 隐式解包的选项真的是可选的吗?

    在 Swift 4 0 中 以下代码无法编译 var str String func someFunc s inout String someFunc str 现在我想象str属于类型String 事实上 Swift 编译器似乎也同意 无法
  • 在 C# 中解密使用 RSA 在 iPhone 上加密的内容时遇到问题

    到目前为止 我已经花了两天时间研究这个问题 并梳理了我可以使用的所有资源 所以这是最后的手段 我有一个 X509 证书 其公钥已存储在 iPhone 的钥匙串中 此时仅限模拟器 在 ASP NET 方面 我已在证书存储区中使用私钥获取了证书