7

I want to Encrypt a string(Plain Text) with my RSA public key. I have a public key, which sent from the server as a String and with that I created a RSA public key. now I want to use that key to Encrypt my text with padding PKACS12. how can I do that. I went through lots of stack overflow questions and I didn't get any success.

this is how I create the RSA public key,

let serverPublicKey = "Some text with key"

let data2 = Data.init(base64Encoded: serverPublicKey)

let keyDict:[NSObject:NSObject] = [
  kSecAttrKeyType: kSecAttrKeyTypeRSA,
  kSecAttrKeyClass: kSecAttrKeyClassPublic,
  kSecAttrKeySizeInBits: NSNumber(value: 2048),
  kSecReturnPersistentRef: true as NSObject
 ]

let publickeysi = SecKeyCreateWithData(data2! as CFData, keyDict as CFDictionary, nil)

this creates a RSA public key successfully. now I want to use this key to encrypt my another Plain Text. how can I do that.

caldera.sac
  • 4,918
  • 7
  • 37
  • 69
  • 1
    Wait.. you receive a public key from a server, and with that key you want to create another public key? Are you sure about that? –  Aug 23 '17 at 10:30
  • its actually not a key, its a `String` with `server public key`. with that I create a `RSA public key` – caldera.sac Aug 23 '17 at 10:32
  • 1
    Ok, so your question is basically "How to use RSA encryption with swift", correct? –  Aug 23 '17 at 10:35
  • @DavidG yep. correct – caldera.sac Aug 23 '17 at 10:35
  • I see. What have you tried so far? Did you look into tutorials and run some example code? If yes, where exactly are you stuck? Update your post with the code in question, highlight the problematic part and add a brief description of what you tried to fix it. –  Aug 23 '17 at 10:38
  • If you are happy to use open source code, take a look at SwiftyRSA. – Paulw11 Aug 23 '17 at 12:08
  • per @Paulw11: [SwiftyRSA](https://github.com/TakeScoop/SwiftyRSA). Looks good, good documentation and comments. – zaph Aug 23 '17 at 15:29

2 Answers2

9

Hope this will help you:

let serverPublicKey = "Some text with key"

    let data2 = Data.init(base64Encoded: serverPublicKey)

    let keyDict:[NSObject:NSObject] = [
      kSecAttrKeyType: kSecAttrKeyTypeRSA,
      kSecAttrKeyClass: kSecAttrKeyClassPublic,
      kSecAttrKeySizeInBits: NSNumber(value: 2048),
      kSecReturnPersistentRef: true as NSObject
     ]

    let publickeysi = SecKeyCreateWithData(data2! as CFData, keyDict as CFDictionary, nil)

    //Encrypt a string with the public key
            let message = "This is my message."
            let blockSize = SecKeyGetBlockSize(publickeysi!)
            var messageEncrypted = [UInt8](repeating: 0, count: blockSize)
            var messageEncryptedSize = blockSize

            var status: OSStatus!

            status = SecKeyEncrypt(publickeysi!, SecPadding.PKCS1, message, message.characters.count, &messageEncrypted, &messageEncryptedSize)

            if status != noErr {
                print("Encryption Error!")
                return
            }
Torongo
  • 1,021
  • 1
  • 7
  • 14
9
import Foundation
import Security


struct RSA {

static func encrypt(string: String, publicKey: String?) -> String? {
    guard let publicKey = publicKey else { return nil }

    let keyString = publicKey.replacingOccurrences(of: "-----BEGIN RSA PUBLIC KEY-----\n", with: "").replacingOccurrences(of: "\n-----END RSA PUBLIC KEY-----", with: "")
    guard let data = Data(base64Encoded: keyString) else { return nil }

    var attributes: CFDictionary {
        return [kSecAttrKeyType         : kSecAttrKeyTypeRSA,
                kSecAttrKeyClass        : kSecAttrKeyClassPublic,
                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 encrypt(string: string, publicKey: secKey)
}

static func encrypt(string: String, publicKey: SecKey) -> String? {
    let buffer = [UInt8](string.utf8)

    var keySize   = SecKeyGetBlockSize(publicKey)
    var keyBuffer = [UInt8](repeating: 0, count: keySize)

    // Encrypto  should less than key length
    guard SecKeyEncrypt(publicKey, SecPadding.PKCS1, buffer, buffer.count, &keyBuffer, &keySize) == errSecSuccess else { return nil }
    return Data(bytes: keyBuffer, count: keySize).base64EncodedString()
   }
}

Use like this

var pemString = "-----BEGIN RSA PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAl/zjMK4w1XZAnpIqLeTAMW7cEUNIifP3HjmUavvc2+oPG1QjNCfxQM6LulZSl6qRim2JGxbc3yvnbMRJqch6IhJ/ysbTekVSqOjskIRGxq0pg0J8PqF3ZZQK6D7BYHi6iaJUMVV0ISB5LogJouyOWqsZyiEjgPz3jj0HIrh14Q6wPZVMpVbIwQR9nZp5gU5minseCyZfQs3PArgXgnzRPdw7Hb0/NY5OVE2Rz1SFTnda6w12SEu1IsVhVhJz1QteNrwNwJAT6WgZd+xnOZhU3Ei+EQK2SijfEGqmWNt1utJygK/0APy8w7VTol7ygbqfuHevGcg90QEXjxZKCjkXkQIDAQAB\n-----END RSA PUBLIC KEY-----"


let password = "abcdefg"
let encryptedPassword = RSA.encrypt(string: password, publicKey: pemString)
print(encryptedPassword)
Den
  • 3,179
  • 29
  • 26