Verify digital signature with public key in iOS - ios

How to Verify digital signature with public key in iOS without using any third party code(e.g.) open SSL?
I need to verify Digital signature in iOS App with a public key. Can some one help me how to achieve that without using third party software.
I am trying below code but the problem is I don't have certificate in my App so can not create SecTrustRef.
CODE:
NSString *certPath = [[NSBundle mainBundle] pathForResource:#"yyy"
ofType:#"xxx"];
SecCertificateRef myCertificate = nil;
NSData *certificateData = [[NSData alloc] initWithContentsOfFile :certPath];
myCertificate = SecCertificateCreateWithData(kCFAllocatorDefault, (__bridge CFDataRef)certificateData);
SecPolicyRef myPolicy = SecPolicyCreateBasicX509();
SecTrustRef trustRef;
SecTrustCreateWithCertificates(myCertificate, myPolicy, &trustRef);
SecKeyRef keyRef = SecTrustCopyPublicKey (trustRef);
BOOL status = SecKeyRawVerify (keyRef,
kSecPaddingPKCS1SHA1,
(const uint8_t *)[data bytes],
(size_t)[data length],
(const uint8_t *)[signature bytes],
(size_t)[signature length]
);
I have the following:
Public Key (NSString*)
Signature (NSString*)
Data (NSString*)
Please help me what all option I have in iOS SDK if I don't want to use ant third party open source.

You can package your public key in a X509 certificate to use the iOS built in functions easily, using openSSL:
openssl req -x509 -out public_key.pem -outform pem -new -newkey rsa:2048 -keyout private_key.pem
the PEM format is base64 encoded, you can switch the -outform to DER to get binary file.
you can import the PEM format by adding a const NSString to your program and adding category to NSData with this function:
- (id) initWithBase64EncodedString:(NSString *) string {
NSMutableData *mutableData = nil;
if( string ) {
unsigned long ixtext = 0;
unsigned long lentext = 0;
unsigned char ch = 0;
unsigned char inbuf[4], outbuf[3]; // buffer sizes fixed by AOL LLC
short i = 0, ixinbuf = 0;
BOOL flignore = NO;
BOOL flendtext = NO;
NSData *base64Data = nil;
const unsigned char *base64Bytes = nil;
// Convert the string to ASCII data.
base64Data = [string dataUsingEncoding:NSASCIIStringEncoding];
base64Bytes = [base64Data bytes];
mutableData = [NSMutableData dataWithCapacity:[base64Data length]];
lentext = [base64Data length];
while( YES ) {
if( ixtext >= lentext ) break;
ch = base64Bytes[ixtext++];
flignore = NO;
if( ( ch >= 'A' ) && ( ch <= 'Z' ) ) ch = ch - 'A';
else if( ( ch >= 'a' ) && ( ch <= 'z' ) ) ch = ch - 'a' + 26;
else if( ( ch >= '0' ) && ( ch <= '9' ) ) ch = ch - '0' + 52;
else if( ch == '+' ) ch = 62;
else if( ch == '=' ) flendtext = YES;
else if( ch == '/' ) ch = 63;
else flignore = YES;
if( ! flignore ) {
short ctcharsinbuf = 3;
BOOL flbreak = NO;
if( flendtext ) {
if( ! ixinbuf ) break;
if( ( ixinbuf == 1 ) || ( ixinbuf == 2 ) ) ctcharsinbuf = 1;
else ctcharsinbuf = 2;
ixinbuf = 3;
flbreak = YES;
}
inbuf [ixinbuf++] = ch;
if( ixinbuf == 4 ) {
ixinbuf = 0;
outbuf [0] = ( inbuf[0] << 2 ) | ( ( inbuf[1] & 0x30) >> 4 );
outbuf [1] = ( ( inbuf[1] & 0x0F ) << 4 ) | ( ( inbuf[2] & 0x3C ) >> 2 );
outbuf [2] = ( ( inbuf[2] & 0x03 ) << 6 ) | ( inbuf[3] & 0x3F );
for( i = 0; i < ctcharsinbuf; i++ )
[mutableData appendBytes:&outbuf[i] length:1];
}
if( flbreak ) break;
}
}
}
self = [self initWithData:mutableData];
return self;
}
ofcourse you pull this file into the certificateData
if you want to use your existing public key just pull it out and write it in a X509 cert format using openSSL
$ openssl rsa -in id_rsa -out pub.der -outform DER -pubout
good luck

If your key data is packaged as PKCS12 data, use SecPKCS12Import to import it and use the public key.

You need to pass a digest (hash) of your data to the verification function. See iOS: Verifying a File With a Certificate and Signature - Public Key is Wrong, Verification Fails

#interface HDSecurityPolicy :AFSecurityPolicy
#end
#implementation HDSecurityPolicy
///pem formate(base64) -> NSData
- (void)setPinnedCertificates:(NSSet *)pinnedCertificates {
[super setPinnedCertificates:pinnedCertificates];
if (self.pinnedCertificates) {
NSMutableSet *mutablePinnedPublicKeys = [NSMutableSet setWithCapacity:[self.pinnedCertificates count]];
for (NSData *pubCertificate in self.pinnedCertificates) {
id publicKey = [HDSecurityPolicy publicSecKeyFromKeyBits:pubCertificate];
if (!publicKey) {
continue;
}
[mutablePinnedPublicKeys addObject:publicKey];
}
[self setValue:mutablePinnedPublicKeys forKey:#"pinnedPublicKeys"];
}
}
// 从公钥证书文件中获取到公钥的SecKeyRef指针
+ (id)publicSecKeyFromKeyBits:(NSData *)givenData {
NSMutableDictionary *options = [NSMutableDictionary dictionary];
options[(__bridge id)kSecAttrKeyType] = (__bridge id) kSecAttrKeyTypeRSA;
options[(__bridge id)kSecAttrKeyClass] = (__bridge id) kSecAttrKeyClassPublic;
NSError *error = nil;
CFErrorRef ee = (__bridge CFErrorRef)error;
////'SecKeyCreateWithData' is only available on iOS 10.0 or newer
id ret = (__bridge_transfer id)SecKeyCreateWithData((__bridge CFDataRef)givenData, (__bridge CFDictionaryRef)options, &ee);
if (error) {
return nil;
}
return ret;
}
#end

Related

aes cbc encrypt, decrypt result is diffrent(objecitve-c, c#)

i have a code in c# for aes decryption
i want make same encryption result by objective-c
but i failed.. help me
i can fix objective-c code, what can i for this?
c# for decrypt
private static readonly string AES_KEY = "asdfasdfasdfasdf";
private static readonly int BUFFER_SIZE = 1024 * 4;
private static readonly int KEY_SIZE = 128;
private static readonly int BLOCK_SIZE = 128;
static public string Composite(string value)
{
using (AesManaged aes = new AesManaged())
using (MemoryStream ims = new MemoryStream(Convert.FromBase64String(value), false))
{
aes.KeySize = KEY_SIZE;
aes.BlockSize = BLOCK_SIZE;
aes.Mode = CipherMode.CBC;
aes.Key = Encoding.UTF8.GetBytes(AES_KEY);
byte[] iv = new byte[aes.IV.Length];
ims.Read(iv, 0, iv.Length);
aes.IV = iv;
using (ICryptoTransform ce = aes.CreateDecryptor(aes.Key, aes.IV))
using (CryptoStream cs = new CryptoStream(ims, ce, CryptoStreamMode.Read))
using (DeflateStream ds = new DeflateStream(cs, CompressionMode.Decompress))
using (MemoryStream oms = new MemoryStream())
{
byte[] buf = new byte[BUFFER_SIZE];
for (int size = ds.Read(buf, 0, buf.Length); size > 0; size = ds.Read(buf, 0, buf.Length))
{
oms.Write(buf, 0, size);
}
return Encoding.UTF8.GetString(oms.ToArray());
}
}
}
objective-c for encrypt
- (NSString *)AES128EncryptWithKey:(NSString *)key
{
NSData *plainData = [self dataUsingEncoding:NSUTF8StringEncoding];
NSData *encryptedData = [plainData AES128EncryptWithKey:key];
NSString *encryptedString = [encryptedData stringUsingEncodingBase64];
return encryptedString;
}
#import "NSData+AESCrypt.h"
#import <CommonCrypto/CommonCryptor.h>
static char encodingTable[64] =
{
'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P',
'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f',
'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v',
'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/'
};
#implementation NSData (AESCrypt)
- (NSData *)AES128EncryptWithKey:(NSString *)key
{
// 'key' should be 16 bytes for AES128
char keyPtr[kCCKeySizeAES128 + 1]; // room for terminator (unused)
bzero( keyPtr, sizeof( keyPtr ) ); // fill with zeroes (for padding)
// fetch key data
[key getCString:keyPtr maxLength:sizeof( keyPtr ) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
//See the doc: For block ciphers, the output size will always be less than or
//equal to the input size plus the size of one block.
//That's why we need to add the size of one block here
size_t bufferSize = dataLength + kCCBlockSizeAES128;
void *buffer = malloc( bufferSize );
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt( kCCEncrypt, kCCAlgorithmAES128, kCCModeCBC | kCCOptionPKCS7Padding,
keyPtr, kCCKeySizeAES128,
NULL /* initialization vector (optional) */,
[self bytes], dataLength, /* input */
buffer, bufferSize, /* output */
&numBytesEncrypted );
if( cryptStatus == kCCSuccess )
{
//the returned NSData takes ownership of the buffer and will free it on deallocation
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free( buffer ); //free the buffer
return nil;
}
- (NSString *)base64Encoding
{
const unsigned char *bytes = [self bytes];
NSMutableString *result = [NSMutableString stringWithCapacity:self.length];
unsigned long ixtext = 0;
unsigned long lentext = self.length;
long ctremaining = 0;
unsigned char inbuf[3], outbuf[4];
unsigned short i = 0;
unsigned short charsonline = 0, ctcopy = 0;
unsigned long ix = 0;
while( YES )
{
ctremaining = lentext - ixtext;
if( ctremaining <= 0 ) break;
for( i = 0; i < 3; i++ )
{
ix = ixtext + i;
if( ix < lentext ) inbuf[i] = bytes[ix];
else inbuf [i] = 0;
}
outbuf [0] = (inbuf [0] & 0xFC) >> 2;
outbuf [1] = ((inbuf [0] & 0x03) << 4) | ((inbuf [1] & 0xF0) >> 4);
outbuf [2] = ((inbuf [1] & 0x0F) << 2) | ((inbuf [2] & 0xC0) >> 6);
outbuf [3] = inbuf [2] & 0x3F;
ctcopy = 4;
switch( ctremaining )
{
case 1:
ctcopy = 2;
break;
case 2:
ctcopy = 3;
break;
}
for( i = 0; i < ctcopy; i++ )
[result appendFormat:#"%c", encodingTable[outbuf[i]]];
for( i = ctcopy; i < 4; i++ )
[result appendString:#"="];
ixtext += 3;
charsonline += 4;
}
return [NSString stringWithString:result];
}
------------------------------------------------------------
------------------------------------------------------------

extracting bits from NSData bytes

I would like to extract all the bits in the following bits from NSData byte :
status Data byte : <0011...
Result turns all are 0000 0000 0000 0000 . Could you please tell me how to ?
NSData *aData = [valueData subdataWithRange:NSMakeRange(0, 2)]; //16 bit status
status= [self bitsToInt:aData];
NSString *aString = [NSString stringWithFormat:#"%d", status];
int value = [aString intValue];
NSlog(#"sadasd value : ,%d" ,value );
unsigned thbit0 = (1 << 0) & value;
unsigned thbit1 = (1 << 1) & value;
unsigned thbit2 = (1 << 2) & value;
unsigned thbit3 = (1 << 3) & value;
unsigned thbit4 = (1 << 4) & value;
unsigned thbit5 = (1 << 5) & value;
unsigned thbit6 = (1 << 6) & value;
unsigned thbit7 = (1 << 7) & value;
unsigned thbit8 = (1 << 8) & value;
unsigned thbit9 = (1 << 9) & value;
unsigned thbit10 = (1 << 10) & value;
unsigned thbit11= (1 << 11) & value;
unsigned thbit12 = (1 << 12) & value;
..
- (int) bitsToInt : (NSData *) valueDa {
uint8_t * bytePtr = (uint8_t * )[valueDa bytes];
int high = bytePtr[1] >= 0 ? bytePtr[1] : 256 + bytePtr[1];
int low = bytePtr[0] >= 0 ? bytePtr[0] : 256 + bytePtr[0];
return low | (high << 8);
}
You could try to work with bit string instead of integer values with additional bit extracting.
Here is simple decoder:
- (NSString *)getBitsFromData:(NSData *)data
{
NSMutableString *result = [NSMutableString string];
const uint8_t *bytes = [data bytes];
for (NSUInteger i = 0; i < data.length; i++)
{
uint8_t byte = bytes[i];
for (int j = 0; j < 8; j++)
{
((byte >> j) & 1) == 0 ? [result appendString:#"0"] : [result appendString:#"1"];
}
}
return result;
}
Test:
NSString *test = #"test";
NSLog(#"%#", [self getBitsFromData:[test dataUsingEncoding:NSUTF8StringEncoding]]);
Result:
2015-07-29 11:37:31.768 Test[18342:9947704] 00101110101001101100111000101110

Drupal and Objective C Base 64 mismatch

I have this sequence of bytes (printed from an HTML, so apologizes for the ugly format)
193<br/>250<br/>194<br/>129<br/>62<br/>60<br/>12<br/>171<br/>199<br/>96<br/>13<br/>125<br/>166<br/>175<br/>80<br/>85<br/>137<br/>29<br/>15<br/>189<br/>33<br/>231<br/>237<br/>98<br/>165<br/>35<br/>75<br/>250<br/>181<br/>150<br/>35<br/>175<br/>129<br/>174<br/>13<br/>13<br/>121<br/>229<br/>30<br/>173<br/>112<br/>210<br/>2<br/>165<br/>110<br/>113<br/>141<br/>166<br/>102<br/>105<br/>33<br/>82<br/>220<br/>233<br/>118<br/>36<br/>73<br/>88<br/>196<br/>152<br/>15<br/>231<br/>164<br/>119<br/>
When I use the Drupal function: [_password_base64_encode][1] I get the following base64 string:
/fjk/u1DAgulUpETay8IJZM5DoP6briMZCmGuLfZXwOUiqE1tJi5h0bo0IePlpcdaZK6GlRuqFGGMFAaDQCdr/
But when I use this sequence of bytes in my iOS application with the code:
NSString *base64Encoded = [hash base64EncodedStringWithOptions:0];
I get:
wfrCgT48DKvHYA19pq9QVYkdD70h5+1ipSNL
Why this behavior?
Thanks
Ported the function _password_base64_encode to iOS:
- (NSString*)drupalBase64PasswordEncode:(NSData*)data {
NSUInteger count = [data length];
int i = 0;
NSString *itTo64String = #"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
const char *itTo64 = [itTo64String cStringUsingEncoding:NSUTF8StringEncoding];
char *input = [data bytes];
NSMutableString *output = [[NSMutableString alloc] init];
do {
unsigned char value = (unsigned char)input[i++];
int value2;
unsigned char toInsert = itTo64[value & 0x3f];
[output appendString:[NSString stringWithFormat:#"%c" , toInsert]];
if (i < count) {
value2 = value | ((unsigned char)input[i] << 8);
}
toInsert = itTo64[(value2 >> 6) & 0x3f];
[output appendString:[NSString stringWithFormat:#"%c" , toInsert]];
if (i++ >= count) {
break;
}
if (i < count) {
value2 = value2 | ((unsigned char)input[i] << 16);
}
toInsert = itTo64[(value2 >> 12) & 0x3F];
[output appendString:[NSString stringWithFormat:#"%c" , toInsert]];
if (i++ >= count) {
break;
}
toInsert = itTo64[(value2 >> 18) & 0x3F];
[output appendString:[NSString stringWithFormat:#"%c" , toInsert]];
}while(i < count);
return output;
}
The most likely explanation is that you're encoding junk along with your intended string - can you dump the actual string that gets encoded, such as
$string = ' ... ';
var_dump($string);
$base64_string = _password_base64_encode($string);
var_dump($string);
It is most likely that you are including different characters ( breaks, newlines in different format, etc ) than you intended when encoding.
In addition, you might want to compare the output with PHP's native base64_encode function, and compare results.

Implementation of RC4 Encryption and URL encoding in objective c

I've to implement the RC4 encryption algorithm in my application for URL encoding.The sample part is listed below for your reference.
Actual value Before Encryption : 10/28/2013
Expected value After Encryption : ˆ!˜·hÇÔÞò
After URL encoding it should be : %0C%88%21%98%B7h%C7%D4%DE%F2
KEY USED is:#"psw"
I've tried but value after encryption & URL encoding returns in this way:
After encryption : !·hÇÔÞò
After URL encoding : %0C%C2%88%21%C2%98%C2%B7h%C3%87%C3%94%C3%9E%C3%B2
I tried converting the java code into objective c code.The java code works fine ,were as the objective c is not working, which you can see in the above result.
Here is the Java code
import java.net.URLEncoder;
public class RC4 {
private char[] key;
private int[] sbox;
private static final int SBOX_LENGTH = 256;
private static final int KEY_MIN_LENGTH = 1;
public static void main(String[] args) {
try {
RC4 rc4 = new RC4("psw");
char[] result = rc4.encrypt("10/28/2013".toCharArray());
System.out.println("encrypted string:\n"
+ new String(toByteArray(result)));
System.out.println("decrypted string:\n"
+ new String(rc4.decrypt(result)));
System.out.println("decrypted string:\n"
+ URLEncoder.encode(new String(toByteArray(result))));
} catch (InvalidKeyException e) {
System.err.println(e.getMessage());
}
}
static byte[] toByteArray(char[] chars) {
byte[] bytes = new byte[chars.length];
for (int i = 0; i < chars.length; i++) {
// bytes[i*2] = (byte) (chars[i] >> 8);
bytes[i] = (byte) chars[i];
}
return bytes;
}
public RC4(String key) throws InvalidKeyException {
setKey(key);
}
public RC4() {
}
public char[] decrypt(final char[] msg) {
return encrypt(msg);
}
public char[] encrypt(final char[] msg) {
sbox = initSBox(key);
char[] code = new char[msg.length];
int i = 0;
int j = 0;
for (int n = 0; n < msg.length; n++) {
i = (i + 1) % SBOX_LENGTH;
j = (j + sbox[i]) % SBOX_LENGTH;
swap(i, j, sbox);
int rand = sbox[(sbox[i] + sbox[j]) % SBOX_LENGTH];
code[n] = (char) (rand ^ (int) msg[n]);
}
return code;
}
private int[] initSBox(char[] key) {
int[] sbox = new int[SBOX_LENGTH];
int j = 0;
for (int i = 0; i < SBOX_LENGTH; i++) {
sbox[i] = i;
}
for (int i = 0; i < SBOX_LENGTH; i++) {
j = (j + sbox[i] + key[i % key.length]) % SBOX_LENGTH;
swap(i, j, sbox);
}
return sbox;
}
private void swap(int i, int j, int[] sbox) {
int temp = sbox[i];
sbox[i] = sbox[j];
sbox[j] = temp;
}
public void setKey(String key) throws InvalidKeyException {
if (!(key.length() >= KEY_MIN_LENGTH && key.length() < SBOX_LENGTH)) {
throw new InvalidKeyException("Key length has to be between "
+ KEY_MIN_LENGTH + " and " + (SBOX_LENGTH - 1));
}
this.key = key.toCharArray();
}
public class InvalidKeyException extends Exception {
private static final long serialVersionUID = 1L;
public InvalidKeyException(String message) {
super(message);
}
}
}
Its corresponding Objective c Code
-(NSString *)encrypt:(NSString *)string{
[self frameSBox:#"psw"];
unichar code[string.length];
const unichar* buffer = code;
int i = 0;
int j = 0;
for (int n = 0; n < string.length; n++) {
i = (i + 1) % self.SBOX_LENGTH;
j = (j + [[self.sBox objectAtIndex:i]integerValue]) % self.SBOX_LENGTH;
[self swap:i with:j];
int index=([[self.sBox objectAtIndex:i] integerValue]+[[self.sBox objectAtIndex:j] integerValue]);
int rand=([[self.sBox objectAtIndex:(index%self.SBOX_LENGTH)] integerValue]);
code[n]=(rand ^ (int)[string characterAtIndex:n]);
}
buffer = code;
return [NSString stringWithCharacters:buffer length:string.length];
}
-(NSArray *)frameSBox:(NSString *)keyValue{
if (self.sBox == nil) {
self.sBox=[[NSMutableArray alloc]init];
}
self.SBOX_LENGTH=256;
int j = 0;
for (int i = 0; i < self.SBOX_LENGTH; i++) {
[self.sBox addObject:[NSNumber numberWithInteger:i]];
}
for (int i = 0; i < self.SBOX_LENGTH; i++) {
j = (j + [[self.sBox objectAtIndex:i] integerValue] + [keyValue characterAtIndex:(i % keyValue.length)]) % self.SBOX_LENGTH;
[self swap:i with:j];
}
return self.sBox;
}
-(void)swap:(int)i with:(int)j{
id tempObj = [self.sBox objectAtIndex:i];
[self.sBox replaceObjectAtIndex:i withObject:[self.sBox objectAtIndex:j]];
[self.sBox replaceObjectAtIndex:j withObject:tempObj];
}
//I'm calling in a different class by creating the RC4encryptor object
NSString *unescaped = [[RC4StringEncryptor encryptor] encrypt:#"10/28/2013"];
logDebug(#"the value is:%#",unescaped);
NSString *escapedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
NULL,
(__bridge CFStringRef) unescaped,
NULL,
CFSTR("!*'();:#&=+$,/?%#[]\" "),
kCFStringEncodingUTF8));
NSLog(#"escapedString: %#",escapedString);
I've also tried
#import <CommonCrypto/CommonCryptor.h>
#implementation NSData (RC4)
- (NSData *)RC4EncryptWithKey:(NSString *)key {
char keyPtr[kCCKeySizeMinRC4+1];
bzero(keyPtr, sizeof(keyPtr));
[key getCString:keyPtr maxLength:sizeof(keyPtr) encoding:NSUTF8StringEncoding];
NSUInteger dataLength = [self length];
size_t bufferSize = dataLength + kCCKeySizeMinRC4;
void *buffer = malloc(bufferSize);
size_t numBytesEncrypted = 0;
CCCryptorStatus cryptStatus = CCCrypt(kCCEncrypt, kCCAlgorithmRC4, kCCModeRC4,
keyPtr, kCCKeySizeMinRC4,
NULL ,
[self bytes], dataLength,
buffer, bufferSize,
&numBytesEncrypted);
if (cryptStatus == kCCSuccess) {
return [NSData dataWithBytesNoCopy:buffer length:numBytesEncrypted];
}
free(buffer);
return nil;
}
- (NSData*) encryptString:(NSString*)plaintext withKey:(NSString*)key {
return [[plaintext dataUsingEncoding:NSUTF8StringEncoding] RC4EncryptWithKey:key];
}
But this above code doesn't work for me.Kindly help me in this....
Somehow I fixed your code and it encrypts-decrypts perfectly. Here it is:
#interface RC4Crypt()
#property (nonatomic, strong) NSArray * key;
#property (nonatomic, strong) NSMutableArray * sBox;
#end
#implementation RC4Crypt
static const int SBOX_LENGTH = 256;
static const int KEY_MIN_LENGTH = 1;
-(NSString *)encrypt:(NSString *)string withKey:(NSString *)key{
self.sBox = [[self frameSBox:key] mutableCopy];
unichar code[string.length];
int i = 0;
int j = 0;
for (int n = 0; n < string.length; n++) {
i = (i + 1) % SBOX_LENGTH;
j = (j + [[self.sBox objectAtIndex:i]integerValue]) % SBOX_LENGTH;
[self.sBox exchangeObjectAtIndex:i withObjectAtIndex:j];
int index=([self.sBox[i] integerValue]+[self.sBox[j] integerValue]);
int rand=([self.sBox[(index%SBOX_LENGTH)] integerValue]);
code[n]=(rand ^ (int)[string characterAtIndex:n]);
}
const unichar* buffer;
buffer = code;
return [NSString stringWithCharacters:buffer length:string.length];
}
- (NSString*) decrypt:(NSString*)string withKey:(NSString*)key
{
return [self encrypt:string withKey:key];
}
-(NSArray *)frameSBox:(NSString *)keyValue{
NSMutableArray *sBox = [[NSMutableArray alloc] initWithCapacity:SBOX_LENGTH];
int j = 0;
for (int i = 0; i < SBOX_LENGTH; i++) {
[sBox addObject:[NSNumber numberWithInteger:i]];
}
for (int i = 0; i < SBOX_LENGTH; i++) {
j = (j + [sBox[i] integerValue] + [keyValue characterAtIndex:(i % keyValue.length)]) % SBOX_LENGTH;
[sBox exchangeObjectAtIndex:i withObjectAtIndex:j];
}
return [NSArray arrayWithArray:sBox];
}
#end

How to decode / convert a base64 string to NSData?

Hello I am trying to figure out how convert / decode a base64 string in an iOS application to NSData, so I can decrypt the data that I encrypted.
The method I used for converting the NSData to a base 64 string can be found here Is there a similar way to create method to decode / convert the base 64 string to NSData?
This is what I was looking for.
+ (NSData *)base64DataFromString: (NSString *)string
{
unsigned long ixtext, lentext;
unsigned char ch, inbuf[4], outbuf[3];
short i, ixinbuf;
Boolean flignore, flendtext = false;
const unsigned char *tempcstring;
NSMutableData *theData;
if (string == nil)
{
return [NSData data];
}
ixtext = 0;
tempcstring = (const unsigned char *)[string UTF8String];
lentext = [string length];
theData = [NSMutableData dataWithCapacity: lentext];
ixinbuf = 0;
while (true)
{
if (ixtext >= lentext)
{
break;
}
ch = tempcstring [ixtext++];
flignore = false;
if ((ch >= 'A') && (ch <= 'Z'))
{
ch = ch - 'A';
}
else if ((ch >= 'a') && (ch <= 'z'))
{
ch = ch - 'a' + 26;
}
else if ((ch >= '0') && (ch <= '9'))
{
ch = ch - '0' + 52;
}
else if (ch == '+')
{
ch = 62;
}
else if (ch == '=')
{
flendtext = true;
}
else if (ch == '/')
{
ch = 63;
}
else
{
flignore = true;
}
if (!flignore)
{
short ctcharsinbuf = 3;
Boolean flbreak = false;
if (flendtext)
{
if (ixinbuf == 0)
{
break;
}
if ((ixinbuf == 1) || (ixinbuf == 2))
{
ctcharsinbuf = 1;
}
else
{
ctcharsinbuf = 2;
}
ixinbuf = 3;
flbreak = true;
}
inbuf [ixinbuf++] = ch;
if (ixinbuf == 4)
{
ixinbuf = 0;
outbuf[0] = (inbuf[0] << 2) | ((inbuf[1] & 0x30) >> 4);
outbuf[1] = ((inbuf[1] & 0x0F) << 4) | ((inbuf[2] & 0x3C) >> 2);
outbuf[2] = ((inbuf[2] & 0x03) << 6) | (inbuf[3] & 0x3F);
for (i = 0; i < ctcharsinbuf; i++)
{
[theData appendBytes: &outbuf[i] length: 1];
}
}
if (flbreak)
{
break;
}
}
}
return theData;
}

Resources