iphone OS! RSA Encryption with public key generated by Bouncy Castle (Java) - ios

I'm developing an application on iphone. I had an application on Java using encryption (RSA) and I created a Private Key and Public Key. I want use the Public Key in Java application on iphone. For Ex: My Public Key is byte[] publicKey = {0x01,0x02};
How can I use my publicKey to encrypt data on iphone?
I saw CryptoExercise, but i cannot build it (function: SecKeyEncrypt err:EXC_BAD_ACCESS ). Can i use getPublicKeyBits() or getPublicKeyRef()?
Here is my code:
* (NSData *)getPublicKeyBits {
OSStatus sanityCheck = noErr;
//
const char myByteArray[] = {
0x00, -0x79, 0x7C, 0x34,
0x5C, -0x36, 0x36, 0x75,
0x0E, 0x7F, -0x21, -0x05,
0x41, 0x21, 0x4F, -0x30,
0x2D, 0x5F, 0x08, -0x25,
0x07, -0x08, 0x22, -0x09,
0x32, -0x6C, 0x10, 0x1E, 0x5A,
-0x59, -0x14, -0x55, -0x73, 0x21,
0x5E, -0x54, -0x5E, -0x72, 0x37,
-0x31, -0x25, -0x45, 0x3B, 0x7D, -0x3C,
-0x6F, -0x40, -0x7E, 0x74, -0x68, -0x23,
0x42, 0x12, -0x62, -0x66, 0x4D, 0x20, -0x69,
0x28, -0x28, -0x36, -0x71, 0x21, 0x02, -0x32,
-0x19, 0x66, 0x7D, 0x3E, 0x03, 0x49, -0x66, 0x1F,
-0x38, 0x3C, 0x0A, 0x5F, 0x60, 0x1B, -0x75, 0x41, 0x48,
-0x5F, 0x1F, -0x34, -0x31, -0x09, 0x17, 0x23, 0x11, 0x1E,
-0x68, 0x0B, -0x4D, 0x69, -0x3F, -0x27, 0x13, -0x71, -0x6D,
-0x7A, 0x3A, 0x64, 0x2A, 0x6A, -0x6E, 0x3C, 0x04, -0x70, -0x1C};
NSData *publicKeyBits = NSData dataWithBytes: myByteArray length: sizeof(myByteArray);
//
//NSData * publicKeyBits = {1};
NSMutableDictionary * queryPublicKey = [NSMutableDictionary alloc] init;
// Set the public key query dictionary.
queryPublicKey setObject:(id)kSecClassKey forKey:(id)kSecClass;
queryPublicKey setObject:publicTag forKey:(id)kSecAttrApplicationTag;
queryPublicKey setObject:(id)kSecAttrKeyTypeRSA forKey:(id)kSecAttrKeyType;
[queryPublicKey setObject:NSNumber numberWithBool:YES] forKey:(id)kSecReturnData;
// Get the key bits.
sanityCheck = SecItemCopyMatching((CFDictionaryRef)queryPublicKey, (CFTypeRef *)&publicKeyBits);
if (sanityCheck != noErr)
{
printf("sanitycheck error#####");
publicKeyBits = nil;
}
NSLog(#"** public key bits: %s", &publicKeyBits);
queryPublicKey release;
return publicKeyBits;
}
// encrypt message
* (void)encryptWithPublicKey:(uint8_t *)plainBuffer cipherBuffer:(uint8_t *)cipherBuffer
{
NSLog(#"== encryptWithPublicKey()");
NSData* publicKey= [AppController sharedWrapper] getPublicKeyBits;
OSStatus status = noErr;
NSLog(#"** original plain text 0: %s", plainBuffer);
size_t cipherBufferSize = 1;
uint8_t *pPlainText = (uint8_t*)"This is a test";
uint8_t *aCipherText;
size_t *iCipherLength = (size_t*)"1024";
// Error handling
// Encrypt using the public.
printf("begin ecrypt !!!!");
// status = SecKeyEncrypt(publicKey,
// kSecPaddingNone,
// plainBuffer,
// plainBufferSize,
// &cipherBuffer[0],
// &cipherBufferSize
// );
status = SecKeyEncrypt(publicKey,
kSecPaddingNone,
pPlainText,
strlen( (char*)pPlainText) + 1,
aCipherText,
iCipherLength);
printf("end encrypt !!!!");
NSLog(#"encryption result code: %d (size: %d)", status, cipherBufferSize);
NSLog(#"encrypted text: %s", cipherBuffer);
}
Please Help me!
Thank you very much

I'm not 100% following it, but I think your issue could be as follows:
Public/Private key pairs are not used to encrypt data. They are used only to encrypt fixed-size blocks of data, which are short - on the order of the size of the public/private key themselves.
So they way these are used is that the public/private key is used to encrypt [something like] an AES Key - which in-turn is used with a mode (like EBC, etc) to encrypt a stream, or irregularly-sized block of data.
I think you are trying to use the Public/Private keypair to encrypt your user-data, which is likely not the correct size for the public/private key operations - thus your leaking and getting an BAD_ACCESS_ERROR.

Related

iOS 8 Bluetooth LE Central can't write value for characteristic 2A06

I am working on an iPhone app and need to write value on the bluetooth low energy device that support Immediate Alert service using CoreBluetooth framework on iOS 7.0 and 8.0. Connection with the device working perfectly but whenever i try to write a value on the device nothing is happening (the value is not saved on device. So, device is not ringing).
Below is the code used for writing value:
+ (void)writeValueForCharacteristic:(CBCharacteristic *)characteristic peripheral:(CBPeripheral *)peripheral alarm:(BOOL)alarm
{
NSData * data = nil;
if (alarm) {
uint8_t value = 2;
data = [NSData dataWithBytes:&value length:sizeof(value)];
} else {
uint8_t value = 0;
data = [NSData dataWithBytes:&value length:sizeof(value)];
}
[peripheral writeValue:data forCharacteristic:characteristic type:CBCharacteristicWriteWithoutResponse];
}
Logs and status of device before the execution above code:
- (void)beginAlarm
{
NSLog(#"characteristic : %#",discAlertCharacteristic);
NSLog(#"peripheral : %#",discPeripheral);
NSLog(#"service : %#",service);
[BluetoothUtility writeValueForCharacteristic:discAlertCharacteristic peripheral:discPeripheral alarm:YES];
}
characteristic : CBCharacteristic: 0x146ea8d0, UUID = 2A06, properties = 0x14, value = (null), notifying = NO
service : CBService: 0x146ecc90, isPrimary = YES, UUID = 1802
peripheral : CBPeripheral: 0x146dd110, identifier = B0A195DC-7273-B3F5-BA70-0219A61F8904, name = LA-TAG a87, state = connected
I have tested my Bluetooth device using BLE Utility app and its working properly.
if (getCharacteristic.properties.rawValue == 0xE){
let sentValue:[UInt8] = [0x38, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF, 0x02]
let sentData = Data(bytes: sentValue)
self.peripheralDevice.writeValue(sentData, for: getCharacteristic, type: CBCharacteristicWriteType.withResponse)
}

Decoding H264 VideoToolkit API fails with Error -8971 in VTDecompressionSessionCreate

I am trying to write a Video decoder using the Hardware supported Video Toolkit Decoder. But if I try to initialize the decoding session like in the example posted below, I get the error -8971 while calling VTDecompressionSessionCreate. Can anyone tell me what I am doing wrong here?
Thank you and best regards,
Oliver
OSStatus status;
int tmpWidth = sps.EncodedWidth();
int tmpHeight = sps.EncodedHeight();
NSLog(#"Got new Width and Height from SPS - %dx%d", tmpWidth, tmpHeight);
const VTDecompressionOutputCallbackRecord callback = { ReceivedDecompressedFrame, self };
status = CMVideoFormatDescriptionCreate(NULL,
kCMVideoCodecType_H264,
tmpWidth,
tmpHeight,
NULL,
&decoderFormatDescription);
if (status == noErr)
{
// Set the pixel attributes for the destination buffer
CFMutableDictionaryRef destinationPixelBufferAttributes = CFDictionaryCreateMutable(
NULL, // CFAllocatorRef allocator
0, // CFIndex capacity
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
SInt32 destinationPixelType = kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange;
CFDictionarySetValue(destinationPixelBufferAttributes,kCVPixelBufferPixelFormatTypeKey, CFNumberCreate(NULL, kCFNumberSInt32Type, &destinationPixelType));
CFDictionarySetValue(destinationPixelBufferAttributes,kCVPixelBufferWidthKey, CFNumberCreate(NULL, kCFNumberSInt32Type, &tmpWidth));
CFDictionarySetValue(destinationPixelBufferAttributes, kCVPixelBufferHeightKey, CFNumberCreate(NULL, kCFNumberSInt32Type, &tmpHeight));
CFDictionarySetValue(destinationPixelBufferAttributes, kCVPixelBufferOpenGLCompatibilityKey, kCFBooleanTrue);
// Set the Decoder Parameters
CFMutableDictionaryRef decoderParameters = CFDictionaryCreateMutable(
NULL, // CFAllocatorRef allocator
0, // CFIndex capacity
&kCFTypeDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
CFDictionarySetValue(decoderParameters,kVTDecompressionPropertyKey_RealTime, kCFBooleanTrue);
// Create the decompression session
// Throws Error -8971 (codecExtensionNotFoundErr)
status = VTDecompressionSessionCreate(NULL, decoderFormatDescription, decoderParameters, destinationPixelBufferAttributes, &callback, &decoderDecompressionSession);
// release the dictionaries
CFRelease(destinationPixelBufferAttributes);
CFRelease(decoderParameters);
// Check the Status
if(status != noErr)
{
NSLog(#"Error %d while creating Video Decompression Session.", (int)status);
continue;
}
}
else
{
NSLog(#"Error %d while creating Video Format Descripttion.", (int)status);
continue;
}
I also stumbled with kVTVideoDecoderBadDataErr. In my case I was changing the header 0x00000001 with the size of the NAL package which included the 4 bytes of this header, that was the reason. I changed the size to not include these 4 bytes (frame_size = sizeof(NAL) - 4). This size should be encoded in big-endian.
You need to create the CMFormatDescriptionRef from your SPS and PPS like
CMFormatDescriptionRef decoderFormatDescription;
const uint8_t* const parameterSetPointers[2] = { (const uint8_t*)[currentSps bytes], (const uint8_t*)[currentPps bytes] };
const size_t parameterSetSizes[2] = { [currentSps length], [currentPps length] };
status = CMVideoFormatDescriptionCreateFromH264ParameterSets(NULL,
2,
parameterSetPointers,
parameterSetSizes,
4,
&decoderFormatDescription);
Also if you are getting your Video Data in Annex-B format you need to remove the start code and replace it with the 4-Byte size information for the decoder to recognize it as avcc formated (Thats what the 5th parameter to CMVideoFormatDescriptionCreateFromH264ParameterSets is for).
#Joride
refer to http://www.szatmary.org/blog/25
It explains that the header (first) byte of each buffer within a NALU describes the buffer's type. You need to mask off these bits and compare them to the table provided. Note the comment about the bit fields. You need to mask the byte with 0x1f to the type value.

Reading an Encrypted data from a txt file and decrypting it in ios

I Using AES128 Encryption and Decryption Technique for reading an encrypted text from a Text File
and Decrypting but i am unable to decrypt it.
The Data in Text file is Encrypted using AES128 in C#
I am using the following code to decrypt it
Kindly help i am new to Encryption and Decryption in AES12*
- (NSData *)doCipher:(NSData *)plainText key:(NSData *)aSymmetricKey
context:(CCOperation)encryptOrDecrypt padding:(CCOptions *)pkcs7
{
CCCryptorStatus ccStatus = kCCSuccess;
// Symmetric crypto reference.
CCCryptorRef thisEncipher = NULL;
// Cipher Text container.
NSData * cipherOrPlainText = nil;
// Pointer to output buffer.
uint8_t * bufferPtr = NULL;
// Total size of the buffer.
size_t bufferPtrSize = 0;
// Remaining bytes to be performed on.
size_t remainingBytes = 0;
// Number of bytes moved to buffer.
size_t movedBytes = 0;
// Length of plainText buffer.
size_t plainTextBufferSize = 0;
// Placeholder for total written.
size_t totalBytesWritten = 0;
// A friendly helper pointer.
uint8_t * ptr;
// Initialization vector; dummy in this case 0's.
uint8_t iv[kChosenCipherBlockSize];
memset((void *) iv, 0x0, (size_t) sizeof(iv));
NSLog(#"doCipher: plaintext: %#", plainText);
NSLog(#"doCipher: key length: %d", [aSymmetricKey length]);
//LOGGING_FACILITY(plainText != nil, #"PlainText object cannot be nil." );
//LOGGING_FACILITY(aSymmetricKey != nil, #"Symmetric key object cannot be nil." );
//LOGGING_FACILITY(pkcs7 != NULL, #"CCOptions * pkcs7 cannot be NULL." );
//LOGGING_FACILITY([aSymmetricKey length] == kChosenCipherKeySize, #"Disjoint choices for key size." );
plainTextBufferSize = [plainText length];//+kCCBlockSizeAES128;
//LOGGING_FACILITY(plainTextBufferSize > 0, #"Empty plaintext passed in." );
NSLog(#"pkcs7: %d", *pkcs7);
// We don't want to toss padding on if we don't need to
if(encryptOrDecrypt == kCCEncrypt)
{
if(*pkcs7 != kCCOptionECBMode)
{
if((plainTextBufferSize % kChosenCipherBlockSize) == 0)
{
*pkcs7 = 0x0000;
}
else
{
*pkcs7 = kCCOptionPKCS7Padding;
}
}
}
else if(encryptOrDecrypt != kCCDecrypt)
{
NSLog(#"Invalid CCOperation parameter [%d] for cipher context.", *pkcs7 );
}
// Create and Initialize the crypto reference.
ccStatus = CCCryptorCreate(encryptOrDecrypt,
kCCAlgorithmAES128,
*pkcs7,
(const void *)[aSymmetricKey bytes],
kChosenCipherKeySize,
(const void *)iv,
&thisEncipher
);
//LOGGING_FACILITY1( ccStatus == kCCSuccess, #"Problem creating the context, ccStatus == %d.", ccStatus );
// Calculate byte block alignment for all calls through to and including final.
bufferPtrSize = CCCryptorGetOutputLength(thisEncipher, plainTextBufferSize, true);
// Allocate buffer.
bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t) );
// Zero out buffer.
memset((void *)bufferPtr, 0x0, bufferPtrSize);
// Initialize some necessary book keeping.
ptr = bufferPtr;
// Set up initial size.
remainingBytes = bufferPtrSize;
// Actually perform the encryption or decryption.
ccStatus = CCCryptorUpdate(thisEncipher,
(const void *) [plainText bytes],
plainTextBufferSize,
ptr,
remainingBytes,
&movedBytes
);
//LOGGING_FACILITY1( ccStatus == kCCSuccess, #"Problem with CCCryptorUpdate, ccStatus == %d.", ccStatus );
// Handle book keeping.
ptr += movedBytes;
remainingBytes -= movedBytes;
totalBytesWritten += movedBytes;
/* From CommonCryptor.h:
#enum CCCryptorStatus
#abstract Return values from CommonCryptor operations.
#constant kCCSuccess Operation completed normally.
#constant kCCParamError Illegal parameter value.
#constant kCCBufferTooSmall Insufficent buffer provided for specified operation.
#constant kCCMemoryFailure Memory allocation failure.
#constant kCCAlignmentError Input size was not aligned properly.
#constant kCCDecodeError Input data did not decode or decrypt properly.
#constant kCCUnimplemented Function not implemented for the current algorithm.
enum {
kCCSuccess = 0,
kCCParamError = -4300,
kCCBufferTooSmall = -4301,
kCCMemoryFailure = -4302,
kCCAlignmentError = -4303,
kCCDecodeError = -4304,
kCCUnimplemented = -4305
};
typedef int32_t CCCryptorStatus;
*/
// Finalize everything to the output buffer.
ccStatus = CCCryptorFinal(thisEncipher,
ptr,
remainingBytes,
&movedBytes
);
totalBytesWritten += movedBytes;
if(thisEncipher) {
(void) CCCryptorRelease(thisEncipher);
thisEncipher = NULL;
}
//LOGGING_FACILITY1( ccStatus == kCCSuccess, #"Problem with encipherment ccStatus == %d", ccStatus );
if (ccStatus == kCCSuccess)
cipherOrPlainText = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)totalBytesWritten];
else
cipherOrPlainText = nil;
if(bufferPtr) free(bufferPtr);
NSString *string = [[NSString alloc] initWithData:cipherOrPlainText encoding:NSUTF8StringEncoding];
return cipherOrPlainText;
/*
Or the corresponding one-shot call:
ccStatus = CCCrypt( encryptOrDecrypt,
kCCAlgorithmAES128,
typeOfSymmetricOpts,
(const void *)[self getSymmetricKeyBytes],
kChosenCipherKeySize,
iv,
(const void *) [plainText bytes],
plainTextBufferSize,
(void *)bufferPtr,
bufferPtrSize,
&movedBytes
);
*/
}

SecKeyGeneratePair returns errSecUnimplemented

Im attempting to implement an RSA encryption algorithm into my iOS app, but when I attempt to generate a public and private key pair, the function returns me the errSecUnimplemented error. I am using the 5.1 SDK and targeting 5.1 at the moment.
Can I not use this function, or did I set up something wrong in attempting to generate the pair?
Here is my code for the key generation:
SecKeyRef publicKey, privateKey;
CFDictionaryRef parameters;
const void* keys[] = {kSecAttrKeyType, kSecAttrKeyTypeRSA};
int keySize = 1024;
const void *values[] = {kSecAttrKeySizeInBits, &keySize};
parameters = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 2, NULL, NULL);
OSStatus ret = SecKeyGeneratePair(parameters, &publicKey, &privateKey);
if ( ret == errSecSuccess )
{
NSLog(#"Key success!");
}
else
{
NSLog(#"Key Failure! %li", ret);
}
I've revised it to just complete the solution for you. 1) You need to use a CFNumberRef and not a pointer to an int for the numerical value. 2) The values need to be the values, the keys need to be the keys - you were mixing a key and value in each of "keys" and "values".
SInt32 iKeySize = 1024;
CFNumberRef keySize = CFNumberCreate(kCFAllocatorDefault, kCFNumberSInt32Type, &iKeySize);
const void* values[] = { kSecAttrKeyTypeRSA, keySize };
const void* keys[] = { kSecAttrKeyType, kSecAttrKeySizeInBits };
CFDictionaryRef parameters = CFDictionaryCreate(kCFAllocatorDefault, keys, values, 2, NULL, NULL);
SecKeyRef publicKey, privateKey;
OSStatus ret = SecKeyGeneratePair(parameters, &publicKey, &privateKey);
if ( ret == errSecSuccess )
NSLog(#"Key success!");
else
NSLog(#"Key Failure! %li", ret);
Shouldn't this be:
const void* keys[] = {kSecAttrKeyType, kSecAttrKeySizeInBits};
int keySize = 1024;
const void *values[] = {kSecAttrKeyTypeRSA, &keySize};
i.e., the keys should be the keys of the dict and the values the values, currently you have one (key,value) pair in keys and one in values.
Using kCFAllocatorSystemDefault instead of kCFAllocatorDefault return errSecSuccess.

How to initialize struct in6_addr?

I do know one method to do this,
const struct in6_addr naddr6 = { {
0x3f, 0xfe, 0x05, 0x01,
0x00, 0x08, 0x00, 0x00,
0x02, 0x60, 0x97, 0xff,
0xfe, 0x40, 0xef, 0xab
}};
but could not with this,
const struct in6_addr naddr6 =
{ { { 0x3ffe0501, 0x00080000, 0x026097ff, 0xfe40efab } } };
and it seems that I could either 1/2/3 paris of brackets.Why?
thanks.
The portable way to do this is like so:
struct in6_addr s6 = { };
if (!IN6_IS_ADDR_UNSPECIFIED(&s6))
inet_pton(AF_INET6, "2001:db8::1", &s6);
Because one need to indicate which form of the address it is addressing (shown using C99):
const struct in6_addr naddr6 =
{ { .u6_addr32 = { 0x3ffe0501, 0x00080000, 0x026097ff, 0xfe40efab } } };
The first bracket pair is for the in6_addr struct, the second for the union:
struct in6_addr
{
union
{
uint8_t u6_addr8[16];
uint16_t u6_addr16[8];
uint32_t u6_addr32[4];
} in6_u;
};

Resources