ios - 如何在 iOS 中解码 AES-128 数据
问题描述
我正在与需要加密的设备交换数据。根据说明,我的 iOS 应用程序生成一个 RSA 2048 位公钥-私钥对,然后我将公钥发送给设备。
我使用此处显示的 macOS 命令行创建了公钥-私钥对openssl
(因为我无法弄清楚如何让 iOS 做到这一点 - 但这是一个未来的问题):
openssl req -x509 -newkey rsa:2048 -out cert.pem
openssl x509 -in cert.pem -noout -pubkey
cert.pem
我将私钥和公钥中的值复制到我的应用程序中:
let certificate = "MIIDej....GWB"
let privateKey = "MIIFhz...Q=="
let publicKey = "MIIBI...AQAB"
当我向设备发送公钥时,设备很高兴并以 AES-128 格式发回使用我发送的公钥加密的数据。
我在这里不知所措,但我是试图让这个设备工作的人。
有没有办法获取我在我的应用程序中设置为 s 的私钥或证书String
来解码来自设备的数据?
我一直在查看 Security 和 CryptoKit 文档,它让我头晕目眩。
FWIW,我能够使用文件SecCertificateCreateWithData
中的字符串集cert.pem
并读取它的一些信息,如摘要。但我不知道如何应用私钥或使用证书来解码数据。我需要像 Dummies 悬崖笔记之类的东西。
谢谢你。
解决方案
Apple文档描述了如何在 iOS 端生成密钥对。
例子:
let tag = "com.example.keys.mykey".data(using: .utf8)!
let attributes: [String: Any] =
[kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
kSecAttrKeySizeInBits as String: 2048,
kSecPrivateKeyAttrs as String:
[kSecAttrIsPermanent as String: true,
kSecAttrApplicationTag as String: tag]
]
var publicKey: SecKey?
var privateKey: SecKey?
SecKeyGeneratePair(attributes, &publicKey, &privateKey)
更多属性在这里可用。
然后您可以使用方法获取私钥或公钥的外部表示: SecKeyCopyExternalRepresentation。
例子:
var error: Unmanaged<CFError>?
SecKeyCopyExternalRepresentation(secKey, &error) as Data?
要解密 AES-128 数据,您需要使用CCCrypt
. 在这里,您有来自 Apple 支持如何加密数据的示例,但要解密数据,您需要将第一个参数更改为kCCDecrypt
.
例子:
extern NSData * SecDecryptAES128CBCPad(NSData * data, NSData * key, NSData * iv) {
CCCryptorStatus err;
NSMutableData * result;
size_t resultLength;
NSCParameterAssert(key.length == kCCKeySizeAES128);
NSCParameterAssert(iv.length == kCCBlockSizeAES128);
// Padding can expand the data, so we have to allocate space for that. The rule for block
// cyphers, like AES, is that the padding only adds space on encryption (on decryption it
// can reduce space, obviously, but we don't need to account for that) and it will only add
// at most one block size worth of space.
result = [[NSMutableData alloc] initWithLength:[data length] + kCCBlockSizeAES128];
err = CCCrypt(
kCCDecrypt,
kCCAlgorithmAES128,
kCCOptionPKCS7Padding,
key.bytes, key.length,
iv.bytes,
data.bytes, data.length,
result.mutableBytes, result.length,
&resultLength
);
assert(err == kCCSuccess);
// Set the output length to the value returned by CCCrypt. This is necessary because
// we have padding enabled, meaning that we might have allocated more space than we needed.
[result setLength:resultLength];
return result;
}
方法中的参数CCCrypt
(如kCCOptionPKCS7Padding
, iv
)您需要根据您的示例进行调整。
推荐阅读
- svg - 用 svg 裁剪一个圆圈......或者?
- huawei-mobile-services - 我的项目没有看到 HMS Map Kit Api Key 我在哪里犯了错误?
- oracle - 如果子表在 Oracle 中有一条 sysdate 记录,则限制在主表中插入数据
- python - 在 Django 中自动将订单添加到正确的客户
- linux - 使用文件名中的下划线/破折号分隔的单词为 cp 构建目标路径
- colors - 如何在 Java 中使用 Apache Poi 从 XSSFCellStyle 读取单元格背景颜色的 RGB 值
- azure - FHIR服务器的认证和授权
- javascript - 初始化前无法访问词法声明“回调”
- coldfusion - 尝试将base64转换为coldfsuion中的图像,但它显示为黑色图像
- xquery - 如何将映射变量传递给外部函数,如 eval 并在 marklogic xquery 中调用