Encryption with Rsa Public Key on iOS

how to encrypt and decrypt a String(Plain Text) with RSA public key in ios, swift

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
}

RSA Encryption function in Swift 4 from Public Key string

You can do like this way...

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

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

var attributes: CFDictionary {
return [kSecAttrKeyType : kSecAttrKeyTypeRSA,
kSecAttrKeyClass : kSecAttrKeyClassPublic,
kSecAttrKeySizeInBits : 2048,
kSecReturnPersistentRef : kCFBooleanTrue] 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()
}

send RSA public key to iphone and use it to encrypt

This should do what you're asking - it encrypts data with the server's public key. It's not subject to MITM attacks, unless the attacker has a copy of your private key and its password (communicating via non-SSL, however, still is, but the data you encrypt with the server's legit public key will be nearly impossible to decrypt).

I cobbled this together from Apple's docs, this site, the Apple developer forums and probably elsewhere. So thanks to everyone I cribbed code from! This code assumes several things:

  1. You've already generated your RSA key pairs (I'm using a 4096-bit key and it seems speedy enough) and, using the private key, created a DER-encoded certificate called "cert.cer" that you put in your resource bundle of your app (obviously, you can also download the cert from your server, but then you're open to MITM attacks again). By default, OpenSSL generates a PEM encoded cert, so you have to convert it with "openssl x509 -in cert.pem -inform PEM -out cert.cer -outform DER". iOS will barf on PEM. The reason I use a cert is it's actually easier to work with, and is supported in iOS. Using just the public key isn't (though it can be done).

  2. You've added Security.framework to your project and you #import <Security/Security.h>.

/*
Returns an NSData of the encrypted text, or nil if encryption was unsuccessful.

Takes the X.509 certificate as NSData (from dataWithContentsOfFile:, for example)
*/

+(NSData *)encryptString:(NSString *)plainText withX509Certificate:(NSData *)certificate {

SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificate);
SecPolicyRef policy = SecPolicyCreateBasicX509();
SecTrustRef trust;
OSStatus status = SecTrustCreateWithCertificates(cert, policy, &trust);

SecTrustResultType trustResult;
if (status == noErr) {
status = SecTrustEvaluate(trust, &trustResult);
}

SecKeyRef publicKey = SecTrustCopyPublicKey(trust);

const char *plain_text = [plainText UTF8String];
size_t blockSize = SecKeyGetBlockSize(publicKey);
NSMutableData *collectedCipherData = [NSMutableData data];

BOOL success = YES;
size_t cipherBufferSize = blockSize;
uint8_t *cipherBuffer = malloc(blockSize);

int i;
for (i = 0; i < strlen(plain_text); i += blockSize-11) {
int j;
for (j = 0; j < blockSize-11 && plain_text[i+j] != '\0'; ++j) {
cipherBuffer[j] = plain_text[i+j];
}

int result;
if ((result = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, cipherBuffer, j, cipherBuffer, &cipherBufferSize)) == errSecSuccess) {
[collectedCipherData appendBytes:cipherBuffer length:cipherBufferSize];
} else {
success = NO;
break;
}
}

/* Free the Security Framework Five! */
CFRelease(cert);
CFRelease(policy);
CFRelease(trust);
CFRelease(publicKey);
free(cipherBuffer);

if (!success) {
return nil;
}

return [NSData dataWithData:collectedCipherData];
}

Encrypt using RSA Certificate in Swift

The code provided in question doesn't extract the Key from certificate. Rather, it tries to create the SecKey using the certificate string itself. The correct way to do the same is to create a SecCertificate object from the certificate data, then create a SecTrust using the certificate data. Then using the trust, copy the public key to make SecKey object.

The final code will look something like this:

import Foundation
import Security

struct RSA {

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

let certificateString = certificate.replacingOccurrences(of: "-----BEGIN CERTIFICATE-----", with: "").replacingOccurrences(of: "-----END CERTIFICATE-----", with: "").replacingOccurrences(of: "\r", with: "").replacingOccurrences(of: "\n", with: "").replacingOccurrences(of: "\t", with: "").replacingOccurrences(of: " ", with: "")
print(certificateString)

// Convert the certificate string to Data
guard let data = Data(base64Encoded: certificateString) else { return nil }
print(data)

// Create SecCertificate object using certificate data
guard let cer = SecCertificateCreateWithData(nil, data as NSData) else { return nil }

var trust: SecTrust?

// Retrieve a SecTrust using the SecCertificate object. Provide X509 as policy
let status = SecTrustCreateWithCertificates(cer, SecPolicyCreateBasicX509(), &trust)

// Check if the trust generation is success
guard status == errSecSuccess else { return nil }

// Retrieve the SecKey using the trust hence generated
guard let secKey = SecTrustCopyPublicKey(trust!) else { 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()
}
}

var pemString = "-----BEGIN CERTIFICATE-----##Base 64 encoded certificate string##-----END CERTIFICATE-----"

let password = "abcde"
let encryptedPassword = RSA.encrypt(string: password, certificate: pemString)
print(encryptedPassword as Any)

The only change is in the static func encrypt(string: String, certificate: String?) -> String? function.

Using an RSA public key on iOS

I found the necessary code on the Apple Site describing how to strip the ASN.1 header from the Public Key and load it into the KeyChain.

How I using an RSA public key generated and how I encrypted in iOS

this question might help you

RSA implementation's in Objective C

(IOS) RSA Encrypt/Decrypt AES Key



Related Topics



Leave a reply



Submit