0
votes

I'am tying to encrypt string password using RSA . but the function that i'am using is generating the public key which is SecKey data type and that is not what i need because i'm getting the public key from the server response as a String . i used many libraries but also the same, generating public key SecKey .
the class bellow showing what i meant i want to change the function func encryptBase64(text: String, secKey: SecKey) -> String { to be like that func encryptBase64(text: String, publicKey: String) -> String {

class RSAWrapper { private var publicKey : SecKey? private var privateKey : SecKey?

func generateKeyPair(keySize: UInt, privateTag: String, publicTag: String) -> Bool {

    self.publicKey = nil
    self.privateKey = nil


    if (keySize != 512 && keySize != 1024 && keySize != 2048) {
        // Failed
        print("Key size is wrong")
        return false
    }
    let publicKeyParameters: [NSString: AnyObject] = [
        kSecAttrIsPermanent: true as AnyObject,
        kSecAttrApplicationTag: publicTag as AnyObject
    ]
    let privateKeyParameters: [NSString: AnyObject] = [
        kSecAttrIsPermanent: true as AnyObject,
        kSecAttrApplicationTag: publicTag as AnyObject
    ]
    let parameters: [String: AnyObject] = [
        kSecAttrKeyType as String: kSecAttrKeyTypeRSA,
        kSecAttrKeySizeInBits as String: keySize as AnyObject,
        kSecPrivateKeyAttrs as String: privateKeyParameters as AnyObject,
        kSecPublicKeyAttrs as String: publicKeyParameters as AnyObject
    ];

    let status : OSStatus = SecKeyGeneratePair(parameters as CFDictionary, &(self.publicKey), &(self.privateKey))

    return (status == errSecSuccess && self.publicKey != nil && self.privateKey != nil)
}

func encrypt(text: String) -> [UInt8] {
    let plainBuffer = [UInt8](text.utf8)
    var cipherBufferSize : Int = Int(SecKeyGetBlockSize((self.publicKey!)))
    var cipherBuffer = [UInt8](repeating:0, count:Int(cipherBufferSize))

    // Encrypto  should less than key length
    let status = SecKeyEncrypt((self.publicKey)!, SecPadding.PKCS1, plainBuffer, plainBuffer.count, &cipherBuffer, &cipherBufferSize)
    if (status != errSecSuccess) {
        print("Failed Encryption")
    }
    return cipherBuffer
}

func decprypt(encrpted: [UInt8]) -> String? {
    var plaintextBufferSize = Int(SecKeyGetBlockSize((self.privateKey)!))
    var plaintextBuffer = [UInt8](repeating:0, count:Int(plaintextBufferSize))

    let status = SecKeyDecrypt((self.privateKey)!, SecPadding.PKCS1, encrpted, plaintextBufferSize, &plaintextBuffer, &plaintextBufferSize)

    if (status != errSecSuccess) {
        print("Failed Decrypt")
        return nil
    }
    return NSString(bytes: &plaintextBuffer, length: plaintextBufferSize, encoding: String.Encoding.utf8.rawValue)! as String
}


func encryptBase64(text: String, secKey: SecKey) -> String {
    let plainBuffer = [UInt8](text.utf8)
    var cipherBufferSize : Int = Int(SecKeyGetBlockSize((secKey)))
    var cipherBuffer = [UInt8](repeating:0, count:Int(cipherBufferSize))

    // Encrypto  should less than key length
    let status = SecKeyEncrypt((self.publicKey)!, SecPadding.PKCS1, plainBuffer, plainBuffer.count, &cipherBuffer, &cipherBufferSize)
    if (status != errSecSuccess) {
        print("Failed Encryption")
    }

    let mudata = NSData(bytes: &cipherBuffer, length: cipherBufferSize)
    return mudata.base64EncodedString(options: NSData.Base64EncodingOptions.lineLength64Characters)
}

func decpryptBase64(encrpted: String) -> String? {

    let data : NSData = NSData(base64Encoded: encrpted, options: .ignoreUnknownCharacters)!
    let count = data.length / MemoryLayout<UInt8>.size
    var array = [UInt8](repeating: 0, count: count)
    data.getBytes(&array, length:count * MemoryLayout<UInt8>.size)

    var plaintextBufferSize = Int(SecKeyGetBlockSize((self.privateKey)!))
    var plaintextBuffer = [UInt8](repeating:0, count:Int(plaintextBufferSize))

    let status = SecKeyDecrypt((self.privateKey)!, SecPadding.PKCS1, array, plaintextBufferSize, &plaintextBuffer, &plaintextBufferSize)

    if (status != errSecSuccess) {
        print("Failed Decrypt")
        return nil
    }
    return NSString(bytes: &plaintextBuffer, length: plaintextBufferSize, encoding: String.Encoding.utf8.rawValue)! as String
}


func getPublicKey() -> SecKey? {
    return self.publicKey
}

func getPrivateKey() -> SecKey? {
    return self.privateKey
}

}

1

1 Answers

0
votes

The keys concept are:

The server as a key pair

  • Public Key
  • Private key

The application as a key pair too

  • Public Key
  • Private key

So the server should know the app public key and the app should know the server public key.

When the server wants to encrypt some payload to the app, the server encrypts with the app public and send it to the app. The app decrypts the payload with app private key.

When the app wants to encrypt some payload to the server, the app encrypts with the server public key and send it to the server. The server decrypts the payload with server private key.

This is how the communication with key pairs should works.

In your case, you should only need to know the server public key because you only need to send things to the server and you shouldn't need to generate the app key pair.

Check this link in order to encrypt with the server public key.