【问题标题】:Encrypt RSA/ECB/OAEPWithSHA-256AndMGF1Padding Swift加密 RSA/ECB/OAEPWithSHA-256AndMGF1Padding Swift
【发布时间】:2017-11-11 11:43:26
【问题描述】:

我要提前说我对密码学不太了解(仅限基础知识)。我正在尝试实现凭据 OpenHome 服务,并且我想加密密码以将其发送到设备。

设备提供了一个用 C 语言编写的函数,它返回一个如下所示的公钥字符串:

MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCzjFGuEKD0uWxzb47oRbiSP2uDwVJPeWU7m9VXi626V6lameTzdtwj2eYVZTIAsAW7yW4or2skn7oHqFG4GvhMzgMwoQjKFxeCPPFXRSotnt26AN1DhvFJp3V/d+MpmkzI07iWcD5eNe4EVNK9GSE4JOEHhJ/JYBVMiu04XE5aqwIDAQAB

Android 实现已经完成,给出的规格是

RSA/ECB/OAEPWithSHA-256AndMGF1Padding

还有一个网站在加密时给出“说明”

http://wiki.openhome.org/wiki/Av:Developer:CredentialsService

到目前为止,我已经尝试过这些库:

SwiftyRSA、Heimdall、SwCrypt

我真的认为我的主要失败之一是我不明白我拥有什么、我需要什么以及最终如何使用 swift 来实现它。

理想情况下,我最终会拥有类似

的功能
func encryptMessage(message:String, whithPublicKey key:String)->String

非常感谢。

【问题讨论】:

  • 不确定您的错误或障碍是什么!该过程看起来您需要使用 RSA 中的服务器共享的公钥,使用 ECB 块密码和 OAEP 填充来生成密码的加密消息并将其发送回服务器。 OAEPWithSHA-256AndMGF1Padding 是一个非常不寻常的,所以只需检查哪些库支持它。
  • 公钥由服务器提供。所以我假设服务器有一个用于解密消息的私钥。我想知道如何使用提供的公钥和规范加密消息。
  • "到目前为止我已经尝试过这些库..." ...然后呢?什么地方出了错?这些尝试之一的代码在哪里?
  • 用算法rsaEncryptionOAEPSHA256查看SecKeyCreateEncryptedData。如果它开箱即用,并且您了解如何使用它,那就太好了。如果您需要更多帮助,这超出了我在 StackOverflow 答案中所能做的,并且可能需要 iOS 上的非平凡代码(许多加密算法仅在 macOS 上受支持)。如果没有其他人可以指导您完成它,并且您有一些预算,我很乐意讨论咨询协议。请注意,这里的标准算法是 SHA-1,并且得到更广泛的支持。如果您可以更改服务器,那可能会对您有所帮助。

标签: ios swift encryption swift3


【解决方案1】:

经过长时间的研究,我刚刚实现了自己的解决方案,而不是使用库并且不了解发生了什么。知道会发生什么总是好的,在这种情况下它不是火箭科学。

在 iOS 上,如果您想加密/解密,您需要使用存储在钥匙串上的密钥。如果在我的情况下,我已经获得了公钥,我可以导入它,我也可以对私钥做同样的事情。请查看我的 HelperClass Here

然后,仅从 iOS 10 开始,您可以调用这两种方法进行加密和解密

        let error:UnsafeMutablePointer<Unmanaged<CFError>?>? = nil
        let plainData = "A Plain text...".data(using: .utf8)
        if let encryptedMessageData:Data = SecKeyCreateEncryptedData(publicSecKey, .rsaEncryptionOAEPSHA256, plainData! as CFData,error) as Data?{
            print("We have an encrypted message")

            let encryptedMessageSigned = encryptedMessageData.map { Int8(bitPattern: $0) }
            print(encryptedMessageSigned)
            
            if let decryptedMessage:Data = SecKeyCreateDecryptedData(privateSecKey, .rsaEncryptionOAEPSHA256, encryptedMessageData as CFData,error) as Data?{
                print("We have an decrypted message \(String.init(data: decryptedMessage, encoding: .utf8)!)")
            }
            else{
                print("Error decrypting")
            }

        }
        else{
            print("Error encrypting")
        }

另外,如果您想在 iOS 10 之前使用以下功能:

func SecKeyEncrypt(_ key: SecKey, 
             _ padding: SecPadding, 
             _ plainText: UnsafePointer<UInt8>, 
             _ plainTextLen: Int, 
             _ cipherText: UnsafeMutablePointer<UInt8>, 
             _ cipherTextLen: UnsafeMutablePointer<Int>) -> OSStatus

func SecKeyDecrypt(_ key: SecKey, 
             _ padding: SecPadding, 
             _ cipherText: UnsafePointer<UInt8>, 
             _ cipherTextLen: Int, 
             _ plainText: UnsafeMutablePointer<UInt8>, 
             _ plainTextLen: UnsafeMutablePointer<Int>) -> OSStatus

但这些提供的选择较少,而且受到很大限制。

值得一提的是,我的公钥和私钥在 android 上使用

public static String createStringFromPublicKey(Key key) throws Exception {
  X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key.getEncoded());
  return new String(Base64.encode(x509EncodedKeySpec.getEncoded(), Base64.NO_WRAP), "UTF-8");
}

public static String createStringFromPrivateKey(Key key) throws Exception {
  PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key.getEncoded());
  return new String(Base64.encode(pkcs8EncodedKeySpec.getEncoded(), Base64.NO_WRAP), "UTF-8");
}

【讨论】:

  • 您在 Android 上使用哪种密钥格式? .Der 或 .Pem 或 .BKS 谢谢
  • 我没有为android编写代码。我得到了作为字符串的公钥... PKCS1 给你更多线索?
  • 我已经用你的代码试过并给了Java,发现BadPadding来自java的错误。
  • 私有静态字符串 createStringFromPublicKey(Key key) 抛出异常 { X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(key.getEncoded()); return new String(Base64.encode(x509EncodedKeySpec.getEncoded(), Base64.NO_WRAP), "UTF-8"); } 私有静态字符串 createStringFromPrivateKey(Key key) 抛出异常 { PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(key.getEncoded()); return new String(Base64.encode(pkcs8EncodedKeySpec.getEncoded(), Base64.NO_WRAP), "UTF-8"); }
  • 您可能在 android 中使用了不同的填充。
猜你喜欢
  • 2015-11-16
  • 2019-05-27
  • 2020-03-17
  • 2021-11-16
  • 2015-08-31
  • 1970-01-01
  • 2015-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多