iOS swift3 equivalent of "RSA/NONE/OAEPWithSHA256AndMGF1Padding" - ios

I am getting decryption error on sever when I used SwiftyRSA to encrypt a text using publicKey on client.
I have referred this
RSA: encrypt in iOS, decrypt in Java but this is for SHA1.
I am using https://github.com/TakeScoop/SwiftyRSA library.
kSecPaddingOAEP and RSA/NONE/OAEPWithSHA1AndMGF1Padding works. But how Can I make it work for RSA/NONE/OAEPWithSHA256AndMGF1Padding
let str = "Clear Text"
let clear = try ClearMessage(string: str, using: .utf8)
let encrypted = try clear.encrypted(with: publicKey, padding: .OAEP)
I want to encrypt data in swift3 without touching server code.

As far as I know, Apple's security framework, it does not support OAEP padding with a SHA256 hash digest, but it can be done through the OpenSSL library.
https://github.com/x2on/OpenSSL-for-iPhone

Related

Laravel 5 Intervention make base64 blob from POST API unable to init from given binary data

I'm sorry, it may be a couple issues and not sure how to phrase the question properly. OK, tried a number of solutions over 2 days to no avail...thank you in advance for your help!
A photo is sent from an iPad app using POST API in the format of base64 (no meta data, just the base64 blob). I'm trying to simply decode and save locally.
I'm testing using Postman:
...com/api/register?first_name=John&photo=/9j/4AAQSkZJRgABAQAAAQAB...[base 64 image of about 400kb]
In Laravel, I am using Intervention
$jpg_url = "image-".time().".jpg";
$path = "/public/".$jpg_url;
$base=base64_decode($customer['photo']);
Image::make($base)->save($path);
and getting an "Unable to init from given binary data" error.
Here's what I don't quite understand and would appreciate a TIL5 explanation:
- When I save the POST from iPad directly into the DB with the following:
$photo = $customer->photo = $customer['photo']
The blob in mysql looks good, I can manually copy and paste it to a web decoder fine.
However, when I use postman, $photo has "+" in the base64 changed into spaces and the image doesn't render
Is this a datatype issue? I'm receiving a long blob that is trying to be converted into string? What is the best practice of receiving images from a mobile app?

Different AES encryptors give me different results... why?

I have tried using three different libraries to AES-encrypt a string.
When I use the tool found here I get the following results:
Input: "Test"
key: "MyEncryptionKey1MyEncryptionKey1" (256 Bit)
ECB mode.
this gives me the output Cidor8Ph7pZqPw0x2AwIKw==
But when i'm using the libraries in Swift I get different results.
Using RNCryptor
When i'm using RNcryptor i'm using the following code:
class func encryptMessage(message: String) throws -> String {
guard let messageData = message.data(using: .utf8) else { return message }
let cipherData = RNCryptor.encrypt(data: messageData, withPassword: key)
return cipherData.base64EncodedString()
}
output:
AwF8a+HziYkO4iHdcI3jY8p9QAY461DVgkjkYUFMkuh4A2a8FCfa4RgS9Z37QhJGxIL0Q20RE3BL4nmLQVFOfZmBpj8l0wj9YZgqZmrkxRFYQQ==
Using AESCrypt
When i'm using RNcryptor i'm using the following code:
class func encryptMessageAES(message: String) -> String{
guard let encryptedData = AESCrypt.encrypt(message, password: key) else { return message }
return encryptedData
}
Output:
T5/mR8UT/EXeUobPTLhcFA==
Also if i'm using CryptoSwift i'm getting a third result. My co-worker who does Android always gets the same result - matching the web tool.
I am totally new to encryption and I see that i'm doing something wrong. But I can't really realize what. I should also mention that this encryption is only used to not have chat messages in raw strings showing in Firebase, for those who have access to the database.
The definition of AES is quite precise and when things don't work between different implementations it's often due various things build on top of AES. The AES algorithm itself always operates on binary data. The data you encrypt needs to be binary. The key you use to encrypt with, needs to be binary and If an IV is in play, it also needs to be binary.
In all implementations where you provide data to the implementation that are not binary, a choice have been made on how that data is transformed into a format that can be used with AES. Sometimes these transformations are just simple data conversions like hex or base64 decoding, but other times whole new concepts are in play, like deriving encryption keys from passwords.
All of your three examples uses text as input for the Key, and each implementation have made some choice on how to support that.
The first page you link to has chosen to just interpret an ASCII string as a binary key. This is a terrible choice as it (in addition to being incompatible with everything else) effectively eliminates 1-2 bits per bytes of the key, reducing the strength considerable.
In the RNCryptor example you specify the key with withPassword: key. Here the RNCryptor team have chosen to use a PBKDF2 key deriving function to make an actual AES key. This solves a different usecase, where you have an potential weak password that needs stretching to be secure for encryption. If you have an actual key, this is not the way to go.
In the case of AESCrypt you also seems to be providing a password as input. It's not clear how that would be transformed to an actual key.
There is one more value which you’ll have to set in AES which is iv. So try to find that iv in all three libraries. And also try to set same value for iv. And then you may be able to get same results from all libraries.

Decrypting AES-256-CBC in Objective C

I am building an iPhone app which gets a decrypted string via JSON from a PHP backend.
In PHP I am encrypting the string like this:
$encrypt_method = "AES-256-CBC";
$secret_key = 'This is my secret key';
$secret_iv = 'This is my secret iv';
// hash
$key = hash('sha256', $secret_key);
// iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning
$iv = substr(hash('sha256', $secret_iv), 0, 16);
if( $action == 'encrypt' ) {
$output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv);
$output = base64_encode($output);
}
In Objective C I tried to decrypt this string with BBEAS: https://github.com/benoitsan/BBAES
This is the code I have got in Objective C:
NSData* salt = [BBAES IVFromString:#"This is my secret iv"];
NSData *key = [BBAES keyBySaltingPassword:#"This is my secret key" salt:salt keySize:BBAESKeySize256 numberOfIterations:BBAESPBKDF2DefaultIterationsCount];
NSData *decryptedMessage = [BBAES decryptedDataFromString:#"RlVnd01XOE5teTNseDFGQ3JScVhkQT09" IV:salt key:key];
NSLog(#"Decrypted message: %#", decryptedMessage);
The log only shows a null object now.
I have found a duplicate post for C#: How to decrypt an AES-256-CBC encrypted string
EDIT:
Lets say that i can adjust the encoding in PHP. How should I encrypt the string in PHP to be decrypted in Objective C?
You are not doing the same thing in PHP as in iOS. I am not familiar with this BBAES framework, but what you seem to have is a password from which you are generating a 256 bit AES key using PBKDF key derivation, and using that to decrypt the data.
However, in PHP you are hashing your password and using it to encrypt your data, so you are probably using different AES keys for encryption and decryption. And I am not sure that IVs match either.
What you should do is:
In PHP, generate a random 16 byte IV for every encryption you do and use PBKDF key derivation to generate the 256 bit AES key from your password. Keep in mind that the salt and the number of iterations have to be the same in both PHP and iOS. After the encryption, append the IV to the encrypted data and send it.
In iOS, extract the IV from the received ciphertext (the last 16 bytes), generate the AES key from your password the same way you did before using the same salt and number of iterations, and decrypt the data (without the 16 byte IV at the end)
Edit:
As #Zaph pointed out, I forgot to mention that you should use also the same type of padding. BBAES seem to use PKCS7 padding.
To decrypt in Objective C you can use Apples's version of the CommonCrypto C library. It has a man page and there are already several posts that show decryption examples on Stack Overflow for example:
Determine if key is incorrect with CCCrypt kCCOptionPKCS7Padding-Objective C
which comes from the tutorial here:
http://robnapier.net/aes-commoncrypto
This also really helped me:
CCCrypt decrypting in AES CBC works even without IV
If you have trouble getting it working post some code.

How to get details from QR code?

I got a string from a qr generated image. But how can I get URL out of it. The string I got is the following.
aHR0cDovL2R1Yml6emxlLWludGVydmlldy5zMy5hbWF6b25hd3MuY29tLzg3M2FhMTA5LnR4dA==
Can anybody help me to get all the information out of it?
Thanks
That string is encoded in Base64. The decoded version of your string is:
http://dubizzle-interview.s3.amazonaws.com/873aa109.txt
If you need to integrate this into your software, find a library that has a Base64 decoder to decode such strings.

String encryption in RubyMotion

I'm trying to encrypt strings in RubyMotion - ideally AES but weaker/older cyphers such as Blowfish should do just fine.
So far I have failed at compiling a couple of pods: RNCrypto and CommonCrypto.
Suggestions? Anyone else tried these pods?
Thank you,
Adrian
If you're having trouble compiling CocoaPods, make sure you run a rake clean. CocoaPods should work fine with RubyMotion as far as I know.
EDIT: Since the OP hasn't posted his solution as the answer, I'll post it here:
RNCryptor doesn't build for iOS6, and there's a pull for ARC compatibility but not yet integrated in the pod.
As for CommonCrypto, it has an example.m file showcasing its capabilities. This example.m includes a main function which clashes with the one created by RubyMotion. By deleting it, I've managed to make it compile successfully.
Here's the necessary process if you currently want to use CommonCrypto pod:
make sure to include the pod in your Rakefile or perform the equivalent Bundler ritual
don't forget to include app.frameworks << 'Security' in the Rakefile as well
then go to vendor/Pods/CommonCrypto and delete the file example.m
Congratulations, you're all set!
Here's a quick (and dirty) sample:
iv = 'init_vector_here'
key = 'key_here'
plainText = 'This is plain text'
plainData = plainText.dataUsingEncoding(NSUTF8StringEncoding)
ivData = iv.dataUsingEncoding(NSUTF8StringEncoding)
keyData = key.dataUsingEncoding(NSUTF8StringEncoding)
status = NIL
result = plainData.dataEncryptedUsingAlgorithm(0, key: keyData, initializationVector: ivData, options: 0, error: status) # 0 = AES128
p result.base64EncodedString
For Base64 encoding you have to include the 'NSData+Base64' pod.
Thank you #AwDogsGo2Heaven and #Jamon Holmgren for your helpful suggestions!

Resources