在 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 上加密的内容时遇到问题 的相关文章

  • 如何在 Cassandra 中存储无符号整数?

    我通过 Datastax 驱动程序在 Cassandra 中存储一些数据 并且需要存储无符号 16 位和 32 位整数 对于无符号 16 位整数 我可以轻松地将它们存储为有符号 32 位整数 并根据需要进行转换 然而 对于无符号 64 位整
  • C++11 删除重写方法

    Preface 这是一个关于最佳实践的问题 涉及 C 11 中引入的删除运算符的新含义 当应用于覆盖继承父类的虚拟方法的子类时 背景 根据标准 引用的第一个用例是明确禁止调用某些类型的函数 否则转换将是隐式的 例如最新版本第 8 4 3 节
  • 为什么 GCC 不允许我创建“内联静态 std::stringstream”?

    我将直接前往 MCVE include
  • 无限循环与无限递归。两者都是未定义的吗?

    无副作用的无限循环是未定义的行为 看here https coliru stacked crooked com view id 24e0a58778f67cd4举个例子参考参数 https en cppreference com w cpp
  • 如何禁用 iPhone 邮件应用程序中的电话号码链接?

    我的公司正在发送数字电子邮件收据 但遇到了 iPhone Mail 检测数字数据并将其自动链接为电话号码的问题 我已经看到元标记应该可以解决 iPhone 上的 Mobil Safari 中的问题 但该技巧似乎不适用于 Mail 有谁知道如
  • 对类 static constexpr 结构的未定义引用,g++ 与 clang

    这是我的代码 a cp p struct int2 int x y struct Foo static constexpr int bar1 1 static constexpr int2 bar2 1 2 int foo1 return
  • 重载 (c)begin/(c)end

    我试图超载 c begin c end类的函数 以便能够调用 C 11 基于范围的 for 循环 它在大多数情况下都有效 但我无法理解和解决其中一个问题 for auto const point fProjectData gt getPoi
  • C# 列表通用扩展方法与非通用扩展方法

    这是一个简单的问题 我希望 集合类中有通用和非通用方法 例如List
  • 两个静态变量同名(两个不同的文件),并在任何其他文件中 extern 其中一个

    在一个文件中将变量声明为 static 并在另一个文件中进行 extern 声明 我认为这会在链接时出现错误 因为 extern 变量不会在任何对象中看到 因为在其他文件中声明的变量带有限定符 static 但不知何故 链接器 瑞萨 没有显
  • 为什么这个字符串用AesCryptoServiceProvider第二次解密时不相等?

    我在 C VS2012 NET 4 5 中的文本加密和解密方面遇到问题 具体来说 当我加密并随后解密字符串时 输出与输入不同 然而 奇怪的是 如果我复制加密的输出并将其硬编码为字符串文字 解密就会起作用 以下代码示例说明了该问题 我究竟做错
  • 为什么 C# 2.0 之后没有 ISO 或 ECMA 标准化?

    我已经开始学习 C 并正在寻找标准规范 但发现大于 2 0 的 C 版本并未由 ISO 或 ECMA 标准化 或者是我从 Wikipedia 收集到的 这有什么原因吗 因为编写 审查 验证 发布 处理反馈 修订 重新发布等复杂的规范文档需要
  • 空指针与 int 等价

    Bjarne 在 C 编程语言 中写道 空指针与整数零不同 但 0 可以用作空指针的指针初始值设定项 这是否意味着 void voidPointer 0 int zero 0 int castPointer reinterpret cast
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 如何阻止 UITableView moveRowAt IndexPath 在重新排序时留下空白行

    我遇到一个问题 在重新排序 UITableViewCells 时 tableView 不随单元格滚动 仅出现一个空白行 任何后续滚动都会出现数组越界错误 堆栈跟踪中没有我的任何代码 这是该问题的快速视频 http www screencas
  • C++ 继承的内存布局

    如果我有两个类 一个类继承另一个类 并且子类仅包含函数 那么这两个类的内存布局是否相同 e g class Base int a b c class Derived public Base only functions 我读过编译器无法对数
  • 使用特定参数从 SQL 数据库填充组合框

    我在使用参数从 sql server 获取特定值时遇到问题 任何人都可以解释一下为什么它在 winfom 上工作但在 wpf 上不起作用以及我如何修复它 我的代码 private void UpdateItems COMBOBOX1 Ite
  • 对于某些 PDF 文件,LoadIFilter() 返回 -2147467259

    我正在尝试使用 Adob e IFilter 搜索 PDF 文件 我的代码是用 C 编写的 我使用 p invoke 来获取 IFilter 的实例 DllImport query dll SetLastError true CharSet
  • C++ 中的参考文献

    我偶尔会在 StackOverflow 上看到代码 询问一些涉及函数的重载歧义 例如 void foo int param 我的问题是 为什么会出现这种情况 或者更确切地说 你什么时候会有 对参考的参考 这与普通的旧参考有何不同 我从未在现
  • UIView晃动动画

    我试图在按下按钮时使 UIView 摇动 我正在调整我找到的代码http www cimgf com 2008 02 27 core animation tutorial window shake effect http www cimgf
  • 使用 WGL 创建现代 OpenGL 上下文?

    我正在尝试使用 Windows 函数创建 OpenGL 上下文 现代版本 基本上代码就是 创建窗口类 注册班级 创建一个窗口 choose PIXELFORMATDESCRIPTOR并设置它 创建旧版 OpenGL 上下文 使上下文成为当前

随机推荐

  • 如何从 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 方面 我已在证书存储区中使用私钥获取了证书