- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在尝试使用 objective-c 和 C# 来加密和解密字符串。两者在 native 代码中都运行良好,但是当我尝试在 c# 中解密字符串时,在 iOS 中已加密。我收到一些错误。
这是我在 objective-c 中使用的代码
- (NSData *)AES256EncryptWithKey:(NSString *)key Data: (NSData *) data
{
char keyPtr[kCCKeySizeAES256+1]; // room for terminator (unused)
bzero(keyPtr, sizeof(keyPtr)); // fill with zeroes (for padding)
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [data length];
NSData *iv = [@"abcdefghijklmnopqrstuvwxyz123456" dataUsingEncoding:NSUTF8StringEncoding];
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmAES128, kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES256,
[iv bytes] /* initialization vector (optional) */,
[data bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted);
if (cryptStatus == kCCSuccess)
{
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer); //free the buffer;
return nil;
}
想知道如何在 C# 中解密,我给出的 block 大小为 256,ivsize 为 32,并使用了“RijndaelManaged()”。我没有使用盐和密码。错误:类似“填充无效且无法删除”之类的内容。我尝试像 PKCS7 一样设置填充,无,零,但对解密没有任何帮助。
有人能帮忙吗?
编辑:我的 C# 代码在这里
public string DecryptString(string encrypted)
{
string result = null;
_encoder = new UTF8Encoding();
if (!string.IsNullOrWhiteSpace(encrypted) && (encrypted.Length >= 32))
{
var messageBytes = Convert.FromBase64String(encrypted);
using (var rm = new RijndaelManaged())
{
rm.BlockSize = _blockSize;
rm.Key = _encoder.GetBytes("mykey_here");
rm.IV = _encoder.GetBytes("abcdefghijklmnopqrstuvwxyz123456"); ;
rm.Padding = PaddingMode.Zeros;
var decryptor = rm.CreateDecryptor(rm.Key, messageBytes.Take(_ivSize).ToArray());
result = _encoder.GetString(Transform(messageBytes.Skip(_ivSize).ToArray(), decryptor));
}
}
return result;
}
protected byte[] Transform(byte[] buffer, ICryptoTransform transform)
{
byte[] result;
using (var stream = new MemoryStream())
using (var cs = new CryptoStream(stream, transform, CryptoStreamMode.Write))
{
cs.Write(buffer, 0, buffer.Length);
cs.FlushFinalBlock();
result = stream.ToArray();
}
return result;
}
最佳答案
iOS (Common Crypto) 显式指定所有加密参数,C# 代码隐式确定许多参数。这些隐式参数虽然简化了使用,但在尝试实现互操作性时存在问题。
C# 类 RijndaelManaged
允许显式指定参数,更改代码以使用这些参数,特别是 BlockSize
(128
), KeySize
(128
)、Mode
(CipherMode.CBC
) 和Padding
(PaddingMode .PKCS7
). mode
和 Padding
的默认值都可以。参见 RijndaelManaged Documentation
AES 和 Rijndael 不同,特别是 AES 仅使用 128 位(16 字节)的 block 大小,而 Rijndael 允许多种 block 大小。因此需要为 Rijndael 指定 128 位的 block 大小。因此 iv 也是 128 位(16 字节)。两者都支持 128、192 和 256 字节的加密 key 。
使用 AESManaged
类可能比使用 RijndaelManaged
类更好。参见 AesManaged Documentation
C# 端希望数据进行 Base64 编码,iOS 端不显示该编码操作,确保在 iOS 端完成。
由于您使用的是 iv,因此请确保您在两侧都使用 CBC 模式。在 Common Crypto 中,CBC 模式是默认模式,请确保在 C# 端使用 CBC 模式。
确保 C# 端使用 PKCS#7 或 PKCS#5 填充,它们是等效的。看来 PKCS#7 是 C# 端的默认设置,所以这应该没问题。
最好使用指定大小的键,不要依赖默认填充。在 Common Crypto 中, key 大小是明确指定的,如果提供的 key 太短,则会填充空值。 C# 看起来像是通过提供的 key 确定 key 大小,在本例中, key 为 10 个字节,因此解密 key 可能默认为 128 位,并且 key 在内部用空值填充。在 iOS 上,您明确指定了 256 位的 key 大小。这是一个需要修复的不匹配。提供与 iOS 端指定的大小完全相同的 key 。
最后是 iv,C# 代码希望将 iv 添加到加密数据之前,但 iOS 代码没有提供。解决方案是更改 iOS 代码以将 iv 添加到加密代码之前。将 iv 更改为 16 字节,即 AES block 大小。
如果您需要更多帮助,请在加密调用前后最后提供测试数据输入、数据输出、iv 和 key 的十六进制转储。
关于c# - 如何使用 Rijndael 在 iOS 中加密 c# 中的解密字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31067324/
IO 设备如何知道属于它的内存中的值在memory mapped IO 中发生了变化? ? 例如,假设内存地址 0 专用于保存 VGA 设备的背景颜色。当我们更改 memory[0] 中的值时,VGA
我目前正在开发一个使用Facebook sdk登录(通过FBLoginView)的iOS应用。 一切正常,除了那些拥有较旧版本的facebook的人。 当他们按下“使用Facebook登录”按钮时,他
假设我有: this - is an - example - with some - dashesNSRange将使用`rangeOfString:@“-”拾取“-”的第一个实例,但是如果我只想要最后
Card.io SDK提供以下详细信息: 卡号,有效期,月份,年份,CVV和邮政编码。 如何从此SDK获取国家名称。 - (void)userDidProvideCreditCardInfo:(Car
iOS 应用程序如何从网络服务下载图片并在安装过程中将它们安装到用户的 iOS 设备上?可能吗? 最佳答案 您无法控制应用在用户设备上的安装,因此无法在安装过程中下载其他数据。 只需在安装后首次启动应
我曾经开发过一款企业版 iOS 产品,我们公司曾将其出售给大型企业,供他们的员工使用。 该应用程序通过 AppStore 提供,企业用户获得了公司特定的配置文件(包含应用程序配置文件)以启用他们有权使
我正在尝试将 Card.io SDK 集成到我的 iOS 应用程序中。我想为 CardIO ui 做一个简单的本地化,如更改取消按钮标题或“在此保留信用卡”提示文本。 我在 github 上找到了这个
我正在使用 CardIOView 和 CardIOViewDelegate 类,没有可以设置为 YES 的 BOOL 来扫描 collectCardholderName。我可以看到它在 CardIOP
我有一个集成了通话工具包的 voip 应用程序。每次我从我的 voip 应用程序调用时,都会在 native 电话应用程序中创建一个新的最近通话记录。我在 voip 应用程序中也有自定义联系人(电话应
iOS 应用程序如何知道应用程序打开时屏幕上是否已经有键盘?应用程序运行后,它可以接收键盘显示/隐藏通知。但是,如果应用程序在分屏模式下作为辅助应用程序打开,而主应用程序已经显示键盘,则辅助应用程序不
我在模拟器中收到以下错误: ImageIO: CGImageReadSessionGetCachedImageBlockData *** CGImageReadSessionGetCachedIm
如 Apple 文档所示,可以通过 EAAccessory Framework 与经过认证的配件(由 Apple 认证)进行通信。但是我有点困惑,因为一些帖子告诉我它也可以通过 CoreBluetoo
尽管现在的调试器已经很不错了,但有时找出应用程序中正在发生的事情的最好方法仍然是古老的 NSLog。当您连接到计算机时,这样做很容易; Xcode 会帮助弹出日志查看器面板,然后就可以了。当您不在办公
在我的 iOS 应用程序中,我定义了一些兴趣点。其中一些有一个 Kontakt.io 信标的名称,它绑定(bind)到一个特定的 PoI(我的意思是通常贴在信标标签上的名称)。现在我想在附近发现信标,
我正在为警报提示创建一个 trigger.io 插件。尝试从警报提示返回数据。这是我的代码: // Prompt + (void)show_prompt:(ForgeTask*)task{
您好,我是 Apple iOS 的新手。我阅读并搜索了很多关于推送通知的文章,但我没有发现任何关于 APNS 从 io4 到 ios 6 的新更新的信息。任何人都可以向我提供 APNS 如何在 ios
UITabBar 的高度似乎在 iOS 7 和 8/9/10/11 之间发生了变化。我发布这个问题是为了让其他人轻松找到答案。 那么:在 iPhone 和 iPad 上的 iOS 8/9/10/11
我想我可以针对不同的 iOS 版本使用不同的 Storyboard。 由于 UI 的差异,我将创建下一个 Storyboard: Main_iPhone.storyboard Main_iPad.st
我正在写一些东西,我将使用设备的 iTunes 库中的一部分音轨来覆盖 2 个视频的组合,例如: AVMutableComposition* mixComposition = [[AVMutableC
我创建了一个简单的 iOS 程序,可以顺利编译并在 iPad 模拟器上运行良好。当我告诉 XCode 4 使用我连接的 iPad 设备时,无法编译相同的程序。问题似乎是当我尝试使用附加的 iPad 时
我是一名优秀的程序员,十分优秀!