Hello i am trying to implement an iPhone app the takes notes and encrypts them and then decrypts them when you enter the correct PIN on a UIAlertView. When the Application loads for the first time i have included in my AppDelegate some code thats checks if there is already a public and private key. If not it goes and generates a pair and adds them to the internal storage. When the application starts for the first time it works just fine. Then i terminate the app and open it again and it just hangs when i go into an existing note and try to decrypt it. From the console i can see the it loads the cipher buffer in the decryption method but the textView is never loaded with the decrypted text this time. The Button just stays in a pressed like state and the process doesn't terminate. this is the code.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data2 = [defaults objectForKey:#"publicKey"];
if (data2 == nil) {
encrypt = [[SecKey alloc]init];
[encrypt generateKeyPairRSA];
SecKeyRef publicKey =[encrypt getPublicKeyRef];
SecKeyRef privateKey = [encrypt getPrivateKeyRef];
size_t keySize = SecKeyGetBlockSize(publicKey);
NSData* keyData = [NSData dataWithBytes:publicKey length:keySize];
[[NSUserDefaults standardUserDefaults] setObject:keyData forKey:#"publicKey"];
keySize = SecKeyGetBlockSize(privateKey);
keyData = [NSData dataWithBytes:privateKey length:keySize];
[[NSUserDefaults standardUserDefaults] setObject:keyData forKey:#"privateKey"];
}
When i run the application for the first time this works fine.
- (IBAction)save:(id)sender {
//save the context and dismiss the AddNewNotesViewcontroller
uint8_t *cipherBuffer = NULL;
SecKey *encrypt = [[SecKey alloc]init];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data2 = [defaults objectForKey:#"publicKey"];
encrypt.publicKey =(SecKeyRef)[data2 bytes];
cipherBuffer = [encrypt Encryption:plainTextField.text];
NSMutableData *data = [[NSMutableData alloc]init];
[data appendBytes:cipherBuffer length:strlen((char*)cipherBuffer)+1];
[self.currentNote setNotesTitle:titleField.text];
[self.currentNote setEncryptedText:data];
[self.delegate addNewNoteViewControllerDidSave];
}
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"Decrypt"])
{
UITextField *passcode = [alertView textFieldAtIndex:0];
if ([passcode.text isEqual: #"1234"]) {
SecKey *encrypt = [[SecKey alloc]init];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSData *data2 = [defaults objectForKey:#"publicKey"];
encrypt.publicKey =(SecKeyRef)[data2 bytes];
data2 = [defaults objectForKey:#"privateKey"];
encrypt.privateKey =(SecKeyRef)[data2 bytes];
NSData *etData = [[NSData alloc]init];
etData = [self.currentNote encryptedText];
const void *bytes = [etData bytes];
uint8_t *crypto_data = (uint8_t*)bytes;
NSLog(#"test %s",crypto_data);
NSString *pb =[encrypt Decryption:crypto_data];
self.encryptedText.text =pb;
}
else self.encryptedText.text = #"WRONG PASSWORD";
}
}
This is the decryption process
- (void)decryptWithPrivateKey:(uint8_t *)cipherBuffer plainBuffer:(uint8_t *)plainBuffer
{
OSStatus status = noErr;
size_t cipherBufferSize = strlen((char *)cipherBuffer);
NSLog(#"decryptWithPrivateKey: length of buffer: %lu", BUFFER_SIZE);
NSLog(#"decryptWithPrivateKey: length of input: %lu", cipherBufferSize);
size_t plainBufferSize = BUFFER_SIZE;
status = SecKeyDecrypt([self getPrivateKey],
PADDING,
&cipherBuffer[0],
cipherBufferSize,
&plainBuffer[0],
&plainBufferSize
);
NSLog(#"decryption result code: %ld (size: %lu)", status, plainBufferSize);
NSLog(#"FINAL decrypted text: %s", plainBuffer);
}
-(NSString *)Decryption:(uint8_t *)cipherBuffer {
plainBuffer = (uint8_t *)calloc(CIPHER_BUFFER_SIZE, sizeof(uint8_t));
[self decryptWithPrivateKey:cipherBuffer plainBuffer:plainBuffer];
NSLog(#"DECRYPTED DATA : %s",plainBuffer);
NSString *s = [[NSString alloc] initWithBytes:plainBuffer length:BUFFER_SIZE encoding:NSUTF8StringEncoding];
return s;
}
Any ideas why this is happening? I am guessing it must be that when it tries to retrieve the private key from the NSUserDefaults. Because the first time when the pair is created it is stored in the NSUserDefaults but it is not retrieved later when i decrypt a note because i haven't close the app yet.
Related
I have googling a lot, but any answer help me with this problem:
Code:
MAIN DECRYPT in XRSA.m
- (NSData *) decryptWithString:(NSString *)content {
return [self RSADecryptData:[content dataUsingEncoding:NSUTF8StringEncoding]];
}
LOAD PRIVATE KEY .p12 in XRSA.m
#pragma mark - Private Key (.p12)
-(BOOL)setPrivateKey:(NSString *)privateKeyPath withPassphrase:(NSString *)password{
NSData *pkcs12key = [NSData dataWithContentsOfFile:privateKeyPath];
NSDictionary* options = NULL;
CFArrayRef importedItems = NULL;
if (password) {
options = [NSDictionary dictionaryWithObjectsAndKeys: password, kSecImportExportPassphrase, nil];
}
OSStatus returnCode = SecPKCS12Import((__bridge CFDataRef) pkcs12key,
(__bridge CFDictionaryRef) options,
&importedItems);
if (returnCode != 0) {
NSLog(#"SecPKCS12Import fail");
return FALSE;
}
NSDictionary* item = (NSDictionary*) CFArrayGetValueAtIndex(importedItems, 0);
SecIdentityRef identity = (__bridge SecIdentityRef) [item objectForKey:(__bridge NSString *) kSecImportItemIdentity];
SecIdentityCopyPrivateKey(identity, &privateKey);
if (privateKey == nil) {
NSLog(#"SecIdentityCopyPrivateKey fail");
return FALSE;
}
return TRUE;
}
Decrypt message in XRSA.m
#pragma mark - RSA Decryption
-(NSData *)RSADecryptData:(NSData *)content{
NSAssert(privateKey != nil,#"Private key can not be nil");
size_t cipherLen = content.length;
void *cipher = malloc(cipherLen);
[content getBytes:cipher length:cipherLen];
size_t plainLen = SecKeyGetBlockSize(privateKey) - 12;
void *plain = malloc(plainLen);
//SecKeyDecrypt(<#SecKeyRef key#>, <#SecPadding padding#>, <#const uint8_t *cipherText#>, <#size_t cipherTextLen#>, <#uint8_t *plainText#>, <#size_t *plainTextLen#>)
OSStatus returnCode = SecKeyDecrypt(privateKey, kSecPaddingPKCS1, cipher,cipherLen, plain, &plainLen);
NSData *result = nil;
if (returnCode != 0) {
NSLog(#"SecKeyDecrypt fail. Error Code: %d", (int)returnCode);
}
else {
result = [NSData dataWithBytes:plain
length:plainLen];
}
free(plain);
free(cipher);
return result;
}
in ViewControler.m:
NSString *privatekeyPath = [[NSBundle mainBundle] pathForResource:#"private_key" ofType:#"p12"];
XRSA *rsa2 = [XRSA alloc];
if([rsa2 setPrivateKey:privatekeyPath withPassphrase:#"Xs23tg"]){
NSString *data = #"UKFpmRmyu1TUZLqcgHmCEGnHaT7+0j5fAaf57xzVR2/j/Qe0j+b5Lez7wya3jlARfzRuHSSZctsGs4gK2JX2LEqHmQLX2zRhLSSzyMlLnYPF8X4pjbDY5agjPlWf4FpFJnmwGr2XjdqRJzPZ9NvEJAns5dNKAh0lQ3nc3kDppfg=";
[rsa2 decryptWithString:data];
}
else{
}
In RSADecryptData fuction, OSStaus is always return error code -9809.
Any ideas?
Thanks for your time.
There are a couple of possibilities:
In the line [content getBytes:cipher length:cipherLen]; you are not assigning that result to anything. Perhaps assign it to a const uint8_t * and pass into the SecKeyDecrypt function instead of content.
You should check to ensure that the cipherLen is less than the plainLen value. You didn't mention your key length, but that could be the cause of the failure. If you need to support larger message, you will need to decrypt in smaller chunk and iterate over your cipher.
in my app i store a NSString encrypted in the keychain with this method
NSUInteger fieldHash = [myStringToSave hash];
// Encrypt
NSString *fieldString = [KeychainWrapper securedSHA256DigestHashForPIN:fieldHash];
// Save in Keychain
if ([KeychainWrapper createKeychainValue:fieldString forIdentifier:PASSWORD]) {
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:PASSWORD];
[[NSUserDefaults standardUserDefaults] synchronize];
in the KeychainWrapper.m there is this method
+ (BOOL)createKeychainValue:(NSString *)value forIdentifier:(NSString *)identifier
{
NSMutableDictionary *dictionary = [self setupSearchDirectoryForIdentifier:identifier];
NSData *valueData = [value dataUsingEncoding:NSUTF8StringEncoding];
[dictionary setObject:valueData forKey:(__bridge id)kSecValueData];
// Protect the keychain entry so it's only valid when the device is unlocked.
[dictionary setObject:(__bridge id)kSecAttrAccessibleWhenUnlocked forKey:(__bridge id)kSecAttrAccessible];
// Add.
OSStatus status = SecItemAdd((__bridge CFDictionaryRef)dictionary, NULL);
// If the addition was successful, return. Otherwise, attempt to update existing key or quit (return NO).
if (status == errSecSuccess) {
return YES;
} else if (status == errSecDuplicateItem){
return [self updateKeychainValue:value forIdentifier:identifier];
} else {
return NO;
}
}
and this
+ (NSString *)securedSHA256DigestHashForPIN:(NSUInteger)pinHash
{
// 1
NSString *name = [[NSUserDefaults standardUserDefaults] stringForKey:USERNAME];
name = [name stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
// 2
NSString *computedHashString = [NSString stringWithFormat:#"%#%i%#", name, pinHash, SALT_HASH];
// 3
NSString *finalHash = [self computeSHA256DigestForString:computedHashString];
//NSLog(#"** Computed hash: %# for SHA256 Digest: %#", computedHashString, finalHash);
return finalHash;
}
+ (NSString*)computeSHA256DigestForString:(NSString*)input
{
const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:input.length];
uint8_t digest[CC_SHA256_DIGEST_LENGTH];
CC_SHA256(data.bytes, data.length, digest);
// Setup our Objective-C output.
NSMutableString* output = [NSMutableString stringWithCapacity:CC_SHA256_DIGEST_LENGTH * 2];
// Parse through the CC_SHA256 results (stored inside of digest[]).
for(int i = 0; i < CC_SHA256_DIGEST_LENGTH; i++) {
[output appendFormat:#"%02x", digest[i]];
}
return output;
}
In order to get a value stored in the keychain i'm using this
+ (NSString *)keychainStringFromMatchingIdentifier:(NSString *)identifier
{
NSData *valueData = [self searchKeychainCopyMatchingIdentifier:identifier];
if (valueData) {
NSString *value = [[NSString alloc] initWithData:valueData
encoding:NSUTF8StringEncoding];
return value;
} else {
return nil;
}
}
passing the identifier PASSWORD like this
NSString *myNewString = [KeychainWrapper keychainStringFromMatchingIdentifier:PASSWORD];
The problem is that it come out a string encrypted which i cannot use. Any advice on how to decrypt it?
Thanks in advance
Nothing in the above code encrypts anything. You appear to be running your value through NSString hash and then SHA-256. Both of these are one-way hashes. By design, they cannot be reversed.
In general, this code is very confusing, and it's not clear what you're trying to achieve. You don't usually encrypt data that you're putting into keychain.
Note that your hash function will truncate multi-byte strings (Chinese, for example).
const char *cstr = [input cStringUsingEncoding:NSUTF8StringEncoding];
NSData *data = [NSData dataWithBytes:cstr length:input.length];
This should be:
NSData *data = [input dataUsingEncoding:NSUTF8StringEncoding];
This code is from one of tutorials on Ray Wenderlich's website. See: http://www.raywenderlich.com/6475/basic-security-in-ios-5-tutorial-part-1 for more information
The basic idea is that you encrypt the password before you save it in the keychain, using the methods:
(NSString *)securedSHA256DigestHashForPIN:(NSUInteger)pinHash;
(NSString*)computeSHA256DigestForString:(NSString*)input;
Then when a user enters a password, you can encrypt it the same way and compare the two values to see if the user has entered the correct password. As the other answers says you cannot reverse the encryption to find the password, but you do not need to if you are just comparing the stored password with the entered password.
I think encrypting the password on the way into the keychain maybe overkill as the password should be encrypted and secure anyway, but cant see any harm in doing it anyway (unless you need to retrieve the original password).
If you are looking to encrypt and decrypt a string then check out this question:
AES Encryption for an NSString on the iPhone
I'm trying to encrypt data with an RSA public key using openssl.
I have the Java implementation of what I need to do in Objective-C.
Here's what I have so far:
- (RSA *)rsaFromExponent:(NSString *)exponent modulus:(NSString *)modulus
{
RSA *rsa_pub = RSA_new();
const char *N = [modulus UTF8String];
const char *E = [exponent UTF8String];
if (!BN_hex2bn(&rsa_pub->n, N))
{
// TODO
}
printf("N: %s\n", N);
printf("n: %s\n", BN_bn2dec(rsa_pub->n));
if (!BN_hex2bn(&rsa_pub->e, E))
{
// TODO
}
printf("E: %s\n", E);
printf("e: %s\n", BN_bn2dec(rsa_pub->e));
return rsa_pub;
}
- (NSString *)cleanString:(NSString *)input
{
NSString *output = input;
output = [output stringByReplacingOccurrencesOfString:#"<" withString:#""];
output = [output stringByReplacingOccurrencesOfString:#">" withString:#""];
output = [output stringByReplacingOccurrencesOfString:#" " withString:#""];
return output;
}
// main code
NSString *exponentB64 = #"AQAB";
NSString *modulusB64 = #"AKDbnFpblq7LHfWDfGTR48B34MKaHQosMwVu8cCc6fH2pZ8Ypx/OgzG6VJlKHXeELtlo5tddBSJpwnkEQdvkkmwuOpCkacTTLon6EHqX4WwFW+waqHxmj419SxiDDlo9tsbg7vfFIMpKyGzq1zvTAN3TroW+MxogZfZD3/N6dNTzvBoXe/Ca1e/zVwYXKbiegLMjNwsruz/WvuMiNKTK4U3GEmb0gIODd1shAH10ube8Nrz/e1u9kr25VQ+7kZAFjnkPTp2AvNGYHQt35m1TRMQhTylVwTZqFkHC/jMt7WxuS8q7ftjM828wa1fEWTgWYrdkzmqZSK5CHBYSys/N1Ws=";
// 1. decode base64 (http://projectswithlove.com/projects/NSData_Base64.zip)
NSData *exponent = [NSData dataFromBase64String:exponentB64];
NSData *modulus = [NSData dataFromBase64String:modulusB64];
NSString *exponentHex = [self cleanString:[exponent description]];
NSString *modulusHex = [self cleanString:[modulus description]];
// 2. create RSA public key
RSA *rsa_pub = [self rsaFromExponent:exponentHex modulus:modulusHex];
NSString *user = #"TEST";
// 3. encode base 64
NSData *userData = [user dataUsingEncoding:NSASCIIStringEncoding];
NSString *userB64String = [userData base64EncodedString];
// 4. encrypt
const unsigned char *from = (const unsigned char *)[userB64String cStringUsingEncoding:NSASCIIStringEncoding];
int flen = strlen((const char *)from);
unsigned char *to = (unsigned char *) malloc(RSA_size(rsa_pub));
int padding = RSA_PKCS1_PADDING;
int result = RSA_public_encrypt(flen, from, to, rsa_pub, padding);
if (-1 == result)
{
NSLog(#"WAT?");
}
else
{
NSLog(#"from: %s", from); // echo VEVTVA==
NSLog(#"to: %s", to); // echo something strange with characters like: ~™Ÿû—...
}
// 5. encode base 64
NSString *cipherString = [NSString stringWithCString:(const char *)to
encoding:NSASCIIStringEncoding];
NSData *cipherData = [cipherString dataUsingEncoding:NSASCIIStringEncoding];
NSString *cipherDataB64 = [cipherData base64EncodedString];
NSLog(#"user encrypted b64: %#", cipherDataB64); // echo null :-(
In Java, I have no problem to base64 encode the encrypted data.
I'm sure I'm doing something wrong but I don't know where because it's not something I do everyday.
Or if you know another way to do this with iOS frameworks like Security.framework.
Thanks in advance.
Someone else helped me figure it out. I don't know why but I was assuming that the output buffer from RSA_public_encrypt function would be an ascii string. Though it's just bytes as the documentation says too. The char * type often leads me to think it's gonna store a string (it's so wrong I think it's the last time I make this kind of error).
So from step 5:
// 5. encode base 64
NSData *cipherData = [NSData dataWithBytes:(const void *)to length:result];
NSString *cipherDataB64 = [cipherData base64EncodedString];
NSLog(#"user encrypted b64: %#", cipherDataB64); // now echo the expected value
I implemented a category method on the NSData class which returns a signature of the data using an SHA-1 hash and subsequent encryption with a private key as follows:
- (NSData *)signatureWithKey:(SecKeyRef)keyRef {
if (keyRef == NULL) {
return nil;
}
NSData *sha1Digest = [self dataWithSHA1Digest];
size_t maxLength = SecKeyGetBlockSize(keyRef) - 11;
if ([sha1Digest length] > maxLength) {
NSString *reason = [NSString stringWithFormat:#"Digest is too long to sign with this key, max length is %ld and actual length is %ld", maxLength, (unsigned long)[self length]];
NSException *ex = [NSException exceptionWithName:#"BMInvalidArgumentException" reason:reason userInfo:nil];
#throw ex;
}
#if TARGET_OS_IPHONE
OSStatus status = noErr;
uint8_t *plainBuffer = (uint8_t *)[sha1Digest bytes];
size_t plainBufferSize = [sha1Digest length];
size_t cipherBufferSize = SecKeyGetBlockSize(keyRef);
uint8_t *cipherBuffer = malloc(cipherBufferSize * sizeof(uint8_t));
status = SecKeyRawSign(keyRef,
kSecPaddingPKCS1SHA1,
plainBuffer,
plainBufferSize,
&cipherBuffer[0],
&cipherBufferSize
);
if (status == noErr) {
return [NSData dataWithBytesNoCopy:cipherBuffer length:cipherBufferSize freeWhenDone:YES];
}
free(cipherBuffer);
return nil;
#else
CFErrorRef error = NULL;
SecTransformRef signer = NULL;
CFTypeRef signature = NULL;
if ((signer = SecSignTransformCreate(keyRef, &error))) {
if (SecTransformSetAttribute(
signer,
kSecTransformInputAttributeName,
(CFDataRef)sha1Digest,
&error)) {
signature = SecTransformExecute(signer, &error);
}
}
if (error) {
LogWarn(#"Could not sign: %#", error);
CFRelease(error);
}
if (signer) {
CFRelease(signer);
}
if (signature) {
NSData *data = [NSData dataWithData:(NSData *)signature];
CFRelease(signature);
return data;
} else {
return nil;
}
#endif
}
Now the strange thing is that with the same private key (loaded from a p12 file) I get two different results for iOS and MacOSX when signing the same data. I am completely puzzled by this. You may notice the method above uses a different implementation for MacOSX using security transforms, but even if I use the iOS implementation on MacOSX (which gives a compile warning but works fine) I get the same result.
The method used for loading the private key from file is below:
+ (SecKeyRef)newPrivateKeyRefWithPassword:(NSString *)password fromData:(NSData *)data {
NSMutableDictionary * options = [[NSMutableDictionary alloc] init];
SecKeyRef privateKeyRef = NULL;
// Set the public key query dictionary
//change to your .pfx password here
[options setObject:password forKey:(id)kSecImportExportPassphrase];
CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
OSStatus securityError = SecPKCS12Import((CFDataRef)data,
(CFDictionaryRef)options, &items);
if (securityError == noErr && CFArrayGetCount(items) > 0) {
CFDictionaryRef identityDict = CFArrayGetValueAtIndex(items, 0);
SecIdentityRef identityApp =
(SecIdentityRef)CFDictionaryGetValue(identityDict,
kSecImportItemIdentity);
securityError = SecIdentityCopyPrivateKey(identityApp, &privateKeyRef);
if (securityError != noErr) {
privateKeyRef = NULL;
}
}
[options release];
if (items) CFRelease(items);
return privateKeyRef;
}
And this is the test case I use. Notice that two different strings are printed on iOS and MacOSX:
NSString *test = #"bla";
NSData *testData = [test dataUsingEncoding:NSUTF8StringEncoding];
NSString *p12Path= [[NSBundle mainBundle] pathForResource:#"private_key" ofType:#"p12"];
NSData *p12Data = [NSData dataWithContentsOfFile:p12Path];
SecKeyRef keyRef = [BMSecurityHelper newPrivateKeyRefWithPassword:#"xxxxxxxx" fromData:p12Data];
NSData *signatureData = [testData signatureWithKey:keyRef];
NSString *signatureString = [BMEncodingHelper base64EncodedStringForData:signatureData withLineLength:0];
if (keyRef) CFRelease(keyRef);
NSLog(#"signatureString: %#", signatureString);
It's always nice if you can answer your own question. I missed the following: under MacOSX the security transform also calculates the SHA-1 hash automatically, in contrast with the iOS implementation.
I fixed the problem by adding the following in the MacOSX implementation:
SecTransformSetAttribute(signer, kSecInputIsAttributeName, kSecInputIsDigest, &error)
I have two scenarios of RSA encryption:
Key pair generated by c# app. Public key sent to iOS. iOS app encrypts data with the key and sends it back. The c# app decrypts using the private key. --- Completely implemented and working.
Key pair generated by ios app. Public key sent to c# app. The c# app encrypts the data, base 64 encodes it and sends it to the ios app. The ios app then decrypts the data using the private key. --- Not working.
If I encrypt using the public and private key pair generated on ios it all works, but as soon as I replace it with the base 64 encoded string from c# it fails. I have tried all combinations of padding.
The code is as follows:
SecPadding padding = kSecPaddingPKCS1;
NSMutableArray *keys = [self generateRSAKeyWithKeySizeInBits:1024 publicKeyTag:#"RSA Public Key" privateKeyTag:#"RSA Private Key"];
SecKeyRef test_publicKey = (__bridge SecKeyRef)(keys[0]);
SecKeyRef test_privateKey = (__bridge SecKeyRef)(keys[1]);
const char *sampled_utf8 = "VnWBW/xRyJB48Uxjdl99apczCuS07zhnLvIjnqyZIQqbI4F7kyAezfD1MNlgeTefkHuCRuzogaQTamk2XRwXoBoGy3Agj4ocPK2Wa7vWNGip8X3FAo1eJL+xKoVoqre/ipDjnZNfEUbX91Ru+IqWkbZXD2POlFfuMaTatCl50+U=";
NSString *sampled = [[NSString alloc] initWithUTF8String:sampled_utf8];
Byte sampled_inputData [[sampled lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];//prepare a Byte[]
[[sampled dataUsingEncoding:NSUTF8StringEncoding] getBytes:sampled_inputData];//get the pointer of the data
size_t sampled_inputDataSize = (size_t)[sampled length];
size_t sampled_outputDataSize = EstimateBas64DecodedDataSize(sampled_inputDataSize);//calculate the decoded data size
Byte sampled_outputData[sampled_outputDataSize];//prepare a Byte[] for the decoded data
Base64DecodeData(sampled_inputData, sampled_inputDataSize, sampled_outputData, &sampled_outputDataSize);//decode the data
NSData *sampled_Data = [[NSData alloc] initWithBytes:sampled_outputData length:sampled_outputDataSize];//create a NSData
NSData *test_encrypted_Data = [self encryptString:encoded_toEncrypt RSAPublicKey:test_publicKey padding:padding];
size_t test_encrypted_inputDataSize = (size_t)[test_encrypted_Data length];
Byte *test_encrypted_inputData = (Byte*) malloc(test_encrypted_inputDataSize);
memcpy(test_encrypted_inputData,[test_encrypted_Data bytes],test_encrypted_inputDataSize);
size_t test_encrypted_outputDataSize = EstimateBas64EncodedDataSize(test_encrypted_inputDataSize);//calculate the encoded data size
char* test_encrypted_outputData[test_encrypted_outputDataSize];//prepare a char for the encoded data
Base64EncodeData(test_encrypted_inputData, test_encrypted_inputDataSize, test_encrypted_outputData, &test_encrypted_outputDataSize,false);//encode the data
NSData *test_encrypted_Encoded = [[NSData alloc] initWithBytes:test_encrypted_outputData length:test_encrypted_outputDataSize];//create a NSData object from the decoded data
size_t input_Size = (size_t)[test_encrypted_Encoded length];
Byte *input = (Byte*) malloc(input_Size);
memcpy(input,[test_encrypted_Encoded bytes],input_Size);
size_t output_Size = EstimateBas64DecodedDataSize(input_Size);
char* output[output_Size];
Base64DecodeData(input, input_Size, output, &output_Size);
NSData *res = [[NSData alloc] initWithBytes:output length:output_Size];
NSData *test_decryptedData = [self decryptString:sampled_Data RSAPrivateKey:test_privateKey padding:padding];
-(NSData*)decryptString:(NSData*)original RSAPrivateKey:(SecKeyRef)privateKey padding: (SecPadding)padding
{
#try
{
const unsigned char* original_String = (unsigned char *)[original bytes];
size_t decryptedLength = SecKeyGetBlockSize(privateKey);
uint8_t decrypted[decryptedLength];
OSStatus status = SecKeyDecrypt(privateKey,
padding,
original_String,
[original length],
decrypted,
&decryptedLength);
NSLog(#"result = %#", [self fetchStatus:status]);
if(status == noErr)
{
NSData* decryptedData = [[NSData alloc] initWithBytes:(const void*)decrypted length:decryptedLength];
return decryptedData;
}
else
return nil;
}
#catch (NSException * e)
{
//do nothing
NSLog(#"exception: %#", [e reason]);
}
return nil;
}
- (NSData*)encryptString:(NSString*)original RSAPublicKey:(SecKeyRef)publicKey1 padding:(SecPadding)padding
{
#try
{
Byte encrypt_inputData [[original lengthOfBytesUsingEncoding:NSUTF8StringEncoding]];//prepare a Byte[]
[[original dataUsingEncoding:NSUTF8StringEncoding] getBytes:encrypt_inputData];//get the pointer of the data
size_t encrypt_inputDataSize = (size_t)[original length];
size_t encrypt_outputDataSize = EstimateBas64DecodedDataSize(encrypt_inputDataSize);//calculate the decoded data size
Byte encrypt_outputData[encrypt_outputDataSize];//prepare a Byte[] for the decoded data
Base64DecodeData(encrypt_inputData, encrypt_inputDataSize, encrypt_outputData, &encrypt_outputDataSize);//decode the data
NSData *encryption_Data = [[NSData alloc] initWithBytes:encrypt_outputData length:encrypt_outputDataSize];//create a NSData object from the decoded data
size_t encryptedLength = SecKeyGetBlockSize(publicKey1);
uint8_t* sample = (uint8_t*)[encryption_Data bytes];
size_t text_Size = [encryption_Data length];
uint8_t *encrypted_Data_Bytes;
encrypted_Data_Bytes = malloc(sizeof(uint8_t)*encryptedLength);
memset(encrypted_Data_Bytes,0,encryptedLength);
OSStatus status = SecKeyEncrypt(publicKey1,
padding,
sample,
text_Size,
&encrypted_Data_Bytes[0],
&encryptedLength);
if(status == noErr)
{
NSData* encryptedData = [[NSData alloc] initWithBytes:(const void*)encrypted_Data_Bytes length:encryptedLength];
return encryptedData;
}
else
return nil;
}
#catch (NSException * e)
{
//do nothing
NSLog(#"exception: %#", [e reason]);
}
return nil;
}