首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Android Java代码Swift实现RSA加密/解密

Android Java代码Swift实现RSA加密/解密
EN

Stack Overflow用户
提问于 2021-05-17 08:35:06
回答 1查看 2.3K关注 0票数 2

我有一些来自Java的方法,需要在Swift中实现:

代码语言:javascript
运行
复制
    fun encryptMessage(content: String): String {
        val cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING")
        cipher.init(Cipher.ENCRYPT_MODE, publicKey)
        val encryptedBytes = cipher.doFinal(content.toByteArray())
        val encryptedData = Base64.encodeToString(encryptedBytes, Base64.DEFAULT)
        return ENCRYPT_MARK + encryptedData
    }
​
    fun decryptMessage(content: String): String {
        val cipher = Cipher.getInstance("RSA/ECB/PKCS1PADDING")
        cipher.init(Cipher.DECRYPT_MODE, privateKey)
        var encryptedData = Base64.decode(content.substring(ENCRYPT_MARK.length), Base64.DEFAULT)
        val decryptedBytes = cipher.doFinal(encryptedData)
        return String(decryptedBytes)
    }

我对加密和解密不是很在行。我尝试了我找到的几个库和代码,但没有对我有效。

我需要解密的示例字符串:

代码语言:javascript
运行
复制
"p+KuB7UVUteY8g3HVMxo+7h2xhZQxhPjPayMolqq8EYyIknbQjgqHjC95NR8/le6G0F8SQACrOdj\nTlPU1+o7bZrE8ukI7B35i9sWZns3Y2scA9U7yz8z5KsTZ240+4+Xd7dZwfQ49Z6J7nNOfBR/97pq\n2l1QKe0/SThUEraZyts=\n"

我的私钥:

代码语言:javascript
运行
复制
"-----BEGIN RSA PRIVATE KEY-----\nMIICXQIBAAKBgQDjOUZOZgIYWDMkyhyNb/gsFUDbDB3a+FWwT0d2HE7cd3bqebYLg\nKAMqwpc8nCHR77kO23Nd/U5WKVWwFcHUQVtkMcX4QNDtxSV72LRNaSaQZkwBofw9O\nu338mm1hR0DEYzYPXKuyaP3l5/pvZyvOHrA+i0ZD7pUohEtiDsuNhZbwIDAQABAoG\nBAJoM6q2cWy9GHOaEYHdDwm2guyfHPzaFxxKRrVFWP+EY3XZ6rgF+YwQzsgLyG3ic\nG7+AyyDSg18tymrWXCqJs7Mdrxq3xZmdCzwTcfgxZcwiFG0caK/jbA8rXO60xecag\nZRR+AyWa+2wnwt5xPtFcqk7GhqkWIolzQddW7L3CIuBAkEA9Xw+fnLrbR3WaxTpa3\n88NEEgvyxIS2eGc+lRUbC8w2xX5qDtV8Ak7rxkmXGURJ6tvwyUi/Q+5y+X20mBtt8\nsKwJBAOz0yph9n4iHtC+BL5U+LfpZuUO6uUctbmfXs+fU2glI8rAwXhanBCs0Ph/0\nG7aXmNKHvcSjQ9N5mhTPBvhpcc0CQH4PPTBF5ytzZQY8CNmQzuOuhhhlrwI5uUuQh\npfCgEyCOGlQPlEPdGe8CpTZRGAwc9xlo2pzFFI3mG2dQ6Ua2V0CQQCSMY11e7wbzi\n37SScEWzKezRCimueI5JzDcK/MjuRe6iThU1YZf73wsfDKYh9fDjT5X0pTsa89ID9\nSK1DPnq7ZAkB6ybvpomovyBBgSjjTEwwSHyAIr5HIE2hkDjer6/87/WNKEw1yg11b\ngSoJC67f1xnLj7bv9/EJRPWTokCaRRm/\n-----END RSA PRIVATE KEY-----"

1. SecKeyCreateDecryptedData

代码语言:javascript
运行
复制
let encryptedMessageData = encryptedMessage.data(using: .utf8)
if let decryptedMessage:Data = SecKeyCreateDecryptedData(privateSecKey!, .rsaEncryptionPKCS1, encryptedMessageData as CFData, error) as Data? {
    print("We have an decrypted message \(String.init(data: decryptedMessage, encoding: .utf8)!)")
} else {
    print("Error decrypting")
}

  • 不工作。我得到打印“错误解密”,但变量

中没有错误。

2. SwiftyRSA

代码语言:javascript
运行
复制
    let encrypted = try EncryptedMessage(data: key.data(using: .utf8)!) // try EncryptedMessage(base64Encoded: key)
    
    let privateKey = try PrivateKey(pemEncoded: keyPair.privateKey)
    let decryptedKey = try encrypted.decrypted(with: privateKey, padding: SecPadding.PKCS1)

  • 获取chunkDecryptFailed(索引: 0)错误.

3. CryptorRSA

代码语言:javascript
运行
复制
    let data = base64.data(using: .utf8)!
    let encryptedData = try CryptorRSA.createEncrypted(with: data)
    let decryptedData = try encryptedData.decrypted(with: privateKey, algorithm: .sha1)

  • 获取错误:

错误Domain=NSOSStatusErrorDomain代码=-50 "RSAdecrypt错误输入(err -27)“UserInfo={numberOfErrorsDeep=0,NSDescription=RSAdecrypt错误输入(err -27)}

我甚至尝试用这些代码行来实现解密,但没有成功:

代码语言:javascript
运行
复制
static func decrypt(string: String, privateKey: String?) -> String? {
    guard let privateKey = privateKey else { return nil }
    
    let keyString = privateKey.replacingOccurrences(of: "-----BEGIN RSA PRIVATE KEY-----\n", with: "").replacingOccurrences(of: "\n-----END RSA PRIVATE KEY-----", with: "")
    guard let data = Data(base64Encoded: keyString, options: .ignoreUnknownCharacters) else { return nil }
    
    var attributes: CFDictionary {
        return [kSecAttrKeyType         : kSecAttrKeyTypeRSA,
                kSecAttrKeyClass        : kSecAttrKeyClassPrivate,
                kSecAttrKeySizeInBits   : 2048,
                kSecReturnPersistentRef : true] as CFDictionary
    }
    
    var error: Unmanaged<CFError>? = nil
    guard let secKey = SecKeyCreateWithData(data as CFData, attributes, &error) else {
        print(error.debugDescription)
        return nil
    }
    return decrypt(string: string, privateKey: secKey)
}

static func decrypt(string: String, privateKey: SecKey) -> String?  {
    let buffer = [UInt8](string.utf8)
    
    let keySize = SecKeyGetBlockSize(privateKey)
    var messageDecrypted = [UInt8](repeating: 0, count: keySize)
    var messageDecryptedSize = keySize
    
    var status = SecKeyDecrypt(privateKey, SecPadding.PKCS1, buffer, buffer.count, &messageDecrypted, &messageDecryptedSize)
    
    if status != noErr {
        print("Decryption Error!")
        return nil
    }
    
    let result = String(bytes: messageDecrypted, encoding: .utf8)
    print(result)
    return result
}

我做错了什么?我如何解密这些示例数据?谢谢你的帮助

EN

回答 1

Stack Overflow用户

发布于 2021-05-18 22:35:17

下面,您将看到一个使用随机生成的密钥进行加密和解密的快速示例。为了简单起见,我添加了bang操作符,但它可能只是向您展示了如何使用Swift中的RSA加密和解密数据。

代码语言:javascript
运行
复制
let attributes = [
    kSecAttrKeyType: kSecAttrKeyTypeRSA,
    kSecAttrKeySizeInBits: 2048,
    kSecAttrKeyClass: kSecAttrKeyClassPrivate
] as CFDictionary

var error: Unmanaged<CFError>?
let privateKey = SecKeyCreateRandomKey(attributes, &error)!
let publicKey = SecKeyCopyPublicKey(privateKey)!

let message = Data("Hello World".utf8)

let ciphertext = SecKeyCreateEncryptedData(publicKey, .rsaEncryptionPKCS1, message as CFData, &error)! as Data

print(ciphertext as NSData)

let plaintext = SecKeyCreateDecryptedData(privateKey, .rsaEncryptionPKCS1, ciphertext as CFData, &error)! as Data
print(String(data: plaintext, encoding: .utf8) ?? "Non UTF8")

现在,我们可以用你的钥匙做同样的事。您的密钥当前是PEM格式。您必须删除页眉、页脚和所有换行符才能将其转换为DER,iOS在可能的范围内非常严格。您可以用下面的代码替换上面的一些行。

代码语言:javascript
运行
复制
let keyBytes = Data(base64Encoded: "<your DER encoded bytes>")! as CFData

var error: Unmanaged<CFError>?
let privateKey = SecKeyCreateWithData(keyBytes, attributes, &error)!
let publicKey = SecKeyCopyPublicKey(privateKey)!

所以,我只想告诉你,你的密码文本搞砸了,或者密码文本是用不同于属于你私钥的公钥创建的。我猜第一个,因为我看到一个base64字符串中的新行.

现在,一些重要的注意事项:

  • 不使用您在这里发布的私钥来发布您的产品。它被称为私有密钥,原因是
  • RSA正变得过时,在密钥大小上尤为明显。你不应该使用1024位RSA密钥,它们不安全。切换到至少2048个bits
  • Encryption的密钥是使用公钥进行的,解密是使用私有密钥完成的(如example)
  • Encryption中所示,使用密钥是有限的;只能加密或解密少量数据,并且解密速度慢。如果您需要加密大量数据,并且需要尽可能快地加密,您可能需要查看AES或ChaCha (尽管它们都是对称算法)

P.S.您的编码字符串是:

代码语言:javascript
运行
复制
MIICXQIBAAKBgQDjOUZOZgIYWDMkyhyNb/gsFUDbDB3a+FWwT0d2HE7cd3bqebYLgKAMqwpc8nCHR77kO23Nd/U5WKVWwFcHUQVtkMcX4QNDtxSV72LRNaSaQZkwBofw9Ou338mm1hR0DEYzYPXKuyaP3l5/pvZyvOHrA+i0ZD7pUohEtiDsuNhZbwIDAQABAoGBAJoM6q2cWy9GHOaEYHdDwm2guyfHPzaFxxKRrVFWP+EY3XZ6rgF+YwQzsgLyG3icG7+AyyDSg18tymrWXCqJs7Mdrxq3xZmdCzwTcfgxZcwiFG0caK/jbA8rXO60xecagZRR+AyWa+2wnwt5xPtFcqk7GhqkWIolzQddW7L3CIuBAkEA9Xw+fnLrbR3WaxTpa388NEEgvyxIS2eGc+lRUbC8w2xX5qDtV8Ak7rxkmXGURJ6tvwyUi/Q+5y+X20mBtt8sKwJBAOz0yph9n4iHtC+BL5U+LfpZuUO6uUctbmfXs+fU2glI8rAwXhanBCs0Ph/0G7aXmNKHvcSjQ9N5mhTPBvhpcc0CQH4PPTBF5ytzZQY8CNmQzuOuhhhlrwI5uUuQhpfCgEyCOGlQPlEPdGe8CpTZRGAwc9xlo2pzFFI3mG2dQ6Ua2V0CQQCSMY11e7wbzi37SScEWzKezRCimueI5JzDcK/MjuRe6iThU1YZf73wsfDKYh9fDjT5X0pTsa89ID9SK1DPnq7ZAkB6ybvpomovyBBgSjjTEwwSHyAIr5HIE2hkDjer6/87/WNKEw1yg11bgSoJC67f1xnLj7bv9/EJRPWTokCaRRm/"
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67566384

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档