iOS (OC) compression_decode_buffer() Returns a null value - ios

I have a tool class. The tool class has written a method of decompression of lz4, but the decompression is controlled, and I don't know what is wrong (libcompression.tbd and #include "compression.h" both have). Below is the code:
+ (NSData *)getDecompressedData:(NSData *)compressed
{
size_t dst_buffer_size = 168*217;
uint8_t *dst_buffer = (uint8_t *)malloc(dst_buffer_size);
uint8_t *src_buffer = (uint8_t *)malloc(compressed.length);
size_t compressResultLength = compression_decode_buffer(dst_buffer, dst_buffer_size, src_buffer, dst_buffer_size, NULL, COMPRESSION_LZ4);
NSData *decompressed = [[NSData alloc] initWithBytes:dst_buffer length:compressResultLength];
return decompressed;
}
CompressResultLength this value is 0

I chose this algorithm incorrectly, COMPRESSION_LZ4 should not be selected, COMPRESSION_LZ4_RAW should be selected, the size of the target and the size of the source data were also wrong before the application. I will send the correct code below:
+ (NSData *)getDecompressedData:(NSData *)compressed{
size_t destSize = 217*168;
uint8_t *destBuf = malloc(sizeof(uint8_t) * destSize);
const uint8_t *src_buffer = (const uint8_t *)[compressed bytes];
size_t src_size = compressed.length;
size_t decompressedSize = compression_decode_buffer(destBuf, destSize, src_buffer, src_size,
NULL, COMPRESSION_LZ4_RAW);
MyLog(#"after decompressed. length = %d",decompressedSize) ;
NSData *data = [NSData dataWithBytesNoCopy:destBuf length:decompressedSize freeWhenDone:YES];
return data;}

Related

iOS RSA decryption successful but the decrypted data seems corrupt

The encryption algorithm that I need to implement needs to RSA encrypt a triple des key. However, I'm experiencing the following behaviour:
The triple Des is created without any issues.
The SecKeyGeneratePair is used to generate RSA public and private keys.
The triple Des key K1 and K2 values are encrypted with a public key that is generated.
I then look to decrypt the datablob created above using the private RSA key.
The decryption is successful! However, the K1 and K2 values seems corrupt.
Here is the code used to encrypt the K1 and K2 data:
- (NSData *)performRsaEncryptionOnData:(NSData *)message {
size_t cipherBufferSize = SecKeyGetBlockSize(publicKey);
size_t plainBufferSize = [message length];
uint8_t *plainBuffer = (uint8_t *)calloc(plainBufferSize, sizeof(uint8_t));
uint8_t *cipherBuffer = (uint8_t *)calloc(cipherBufferSize, sizeof(uint8_t));
strncpy( (char *)plainBuffer,[message bytes], plainBufferSize);
SecKeyEncrypt(publicKey, kSecPaddingPKCS1, plainBuffer, plainBufferSize, &cipherBuffer[0], &cipherBufferSize);
return [NSData dataWithBytesNoCopy:cipherBuffer length:cipherBufferSize];
}
Here is the code used to decrypt the data:
- (NSData *)performRsaDecryptionForDataBlob:(NSData *)encryptedData {
size_t plainTextBufferSize = 128;
size_t cipherBufferSize = [encryptedData length];
uint8_t *cipherBuffer = (uint8_t*)[encryptedData bytes];
uint8_t *plainBuffer = (uint8_t *)calloc(plainTextBufferSize, sizeof(uint8_t));
SecKeyDecrypt(privateKey, kSecPaddingPKCS1,cipherBuffer,cipherBufferSize,&plainBuffer[0],&plainTextBufferSize);
return [NSData dataWithBytesNoCopy:plainBuffer length:plainTextBufferSize];
}
Here is the results that I get before RSA encryption: K1K2 = <54b86c29 f9766b00 d90a6c51 1a80026a>, after the decryption this is what we have: K1K2 = <54b86c29 f9766b00 00000000 00000000>. Frankly I'm not entirely sure why this is occuring. Any ideas?
strncpy(..) don't work with binary data. Your key contains a 0 and strncpy(..) stops copying the rest of your key.
K1K2 = <54b86c29 f9766b00 d90a6c51 1a80026a>
^^

iOS a Very Amazing(malloc_error_break)

first this my code
#pragma pack (4)
typedef struct _Login{
char user[32];
char pwd[32];
int userID;
}Login,*PLogin;
const unsigned long MSG_TAG_HEADER_YXHY = 0x59485859;
#pragma pack (2)
typedef struct tagTcpPacketHeader
{
int ulHtag;
char ucVersion;
char ucCmd;
int ulUserId;
short usPacketNum;
int ulDataLen;
}TcpPacketHeader,*LPTcpPacketHeader;
#pragma pack ()
const unsigned int TCP_HEADER_PACKET_LEN = sizeof(TcpPacketHeader);
- (NSData*)sendDataFileWithUserId:(const int)nUserId nCmd:(const int)nCmd pData:(NSData*)data{
NSData* sendData;
void* sendObj = malloc(data.length);
[data getBytes:sendObj length:data.length];
static int nPacketNum = 0;
int nLen = (int)data.length + TCP_HEADER_PACKET_LEN;
char *pTmpBuf = malloc(nLen);
LPTcpPacketHeader tcpHeader = (LPTcpPacketHeader)pTmpBuf;
tcpHeader->ulHtag = MSG_TAG_HEADER_YXHY;
tcpHeader->ucVersion = 1;
tcpHeader->ucCmd = nCmd;
tcpHeader->ulUserId = nUserId;
tcpHeader->usPacketNum = nPacketNum;
tcpHeader->ulDataLen = nLen;
memcpy(tcpHeader + TCP_HEADER_PACKET_LEN,sendObj, data.length);
sendData = [NSData dataWithBytes:pTmpBuf length:nLen];
nPacketNum++;
free(pTmpBuf);
free(sendObj);
return sendData;
}
- (NSData*)get_File_Login:(NSString*)userID{
int length = sizeof(Login);
Login log_in = {"123","456",userID.intValue};
NSData* login_data = [NSData dataWithBytes:&log_in length:length];
NSData* ret = [self sendDataFileWithUserId:log_in.userID nCmd:5 pData:login_data];
return ret;
}
Use
NSData* ms = [self get_File_Login:#"123"];
NSLog(#"%#",ms);
After frequent use can be a problem
question
This question makes me very headache why appear “ set a breakpoint in malloc_error_break to debug ”
I have added the "malloc_error_break" the breakpoint,But it doesn't work......
Who can tell me the answer???
When you use the pointer in memcpy this way
memcpy(tcpHeader + TCP_HEADER_PACKET_LEN,sendObj, data.length);
this means that you want to copy into memory location pointed by tcpHeader plus TCP_HEADER_PACKET_LEN times the size of the data the pointer points to. It is the same as doing &tcpHeader[TCP_HEADER_PACKET_LEN].
Assuming you want to write to a location right after the header there are two ways to fix it:
1) use a pointer with a size of 1, meaning a char*. In your code you have a pointer pTmpBuf that is such so just change the code to:
memcpy(pTmpBuf + TCP_HEADER_PACKET_LEN, sendObj, data.length);
2) use the size 1 for this calculation. Since the size of the data it points to is the same as TCP_HEADER_PACKET_LEN then multiplying it by one gives the correct location:
memcpy(tcpHeader + 1, sendObj, data.length);
I would recommend the first since it's clear what you are calculating. In the second it is unclear why you would add one, as well as using a pointer to one type when copying data that isn't that type.

SecPKCS12Import any time return empty items

This is my code. Any time items return is null.I have tried in swift and objective c,but nothing.
let certName : String = "private_key"//name of the certificate//
//get p12 file path
let resourcePath: String = NSBundle.mainBundle().pathForResource(certName, ofType: "p12")!
let p12Data: NSData = NSData(contentsOfFile: resourcePath)!
//create key dictionary for reading p12 file
let key : NSString = kSecImportExportPassphrase as NSString
let options : NSDictionary = [key : "password"]
//create variable for holding security information
var privateKeyRef: SecKeyRef? = nil
var items : CFArray?
let securityError: OSStatus = SecPKCS12Import(p12Data, options, &items)
print(items)
I'm using pkcs8. And you need to include
#include <CommonCrypto/CommonDigest.h>
#include <openssl/engine.h>
openssl download from Github
+ (NSString*) getSignatureData:(NSString*) signableData {
// get private key path
NSString* path = [[NSBundle mainBundle] pathForResource:#"private"
ofType:#"der"];
NSData* datasss = [signableData dataUsingEncoding:NSNonLossyASCIIStringEncoding];
char* text = (char*) [signableData UTF8String];
unsigned char *data;
data = (unsigned char *) text;
//creates a new file BIO with mode, mode the meaning of mode is the same as the stdio function fopen()
BIO *in = BIO_new_file([path cStringUsingEncoding:NSUTF8StringEncoding], "rb");
//PKCS#8 private key info structure
PKCS8_PRIV_KEY_INFO *p8inf = d2i_PKCS8_PRIV_KEY_INFO_bio(in, NULL);
EVP_PKEY *pkey = EVP_PKCS82PKEY(p8inf);
PKCS8_PRIV_KEY_INFO_free(p8inf);
BIO_free(in);
uint8_t * cipherBuffer = NULL;
// Calculate the buffer sizes.
unsigned int cipherBufferSize = RSA_size(pkey->pkey.rsa);
unsigned int signatureLength;
// Allocate some buffer space.
cipherBuffer = malloc(cipherBufferSize);
memset((void *)cipherBuffer, 0x0, cipherBufferSize);
unsigned char hashedChars[32];
//return a pointer to the hash value
unsigned char *openSSLHash = CC_SHA256(datasss.bytes, (CC_LONG)signableData.length, hashedChars);
//unsigned char *openSSLHash1 = SHA256(data, signableData.length, NULL);
/*
* The following function sign and verify a X509_SIG ASN1 object inside
* PKCS#8 padded RSA encryption
*/
RSA_sign(NID_sha256, openSSLHash, SHA256_DIGEST_LENGTH, cipherBuffer, &signatureLength, pkey->pkey.rsa);
NSData *signedData = [NSData dataWithBytes:(const void*)cipherBuffer length:signatureLength];
EVP_PKEY_free(pkey);
NSString *base64String = [signedData base64EncodedStringWithOptions:0];
return base64String;
}

byteArray to Hex NSString - adds some wrong hex content

I am trying to convert the byteArray to a Hex NSString.
Here is the solution that I referred to convert it into hex NSString. But, I discovered It add's ffffffffffffff. How can I get correct hex NSString?
Best way to serialize an NSData into a hexadeximal string
const char myByteArray[] = {
0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,
0x12,0x23,0x34,0x45,
0x56,0x67,0x78,0x89 };
NSData *myByteData=[NSData dataWithBytes:myByteArray length:sizeof(myByteArray)];
NSMutableString *myHexString= [NSMutableString stringWithCapacity:myByteData.length*2];
for(int i=0;i<myByteData.length;i++){
;
NSString *resultString =[NSString stringWithFormat:#"%02lx",(unsigned long)myByteArray[i]];
[myHexString appendString:resultString];
}
The output String
12233445566778ffffffffffffff8912233445566778ffffffffffffff89
Don't use unsigned long for each of your bytes. And what's the point of myByteData if you don't use it?
And since you are not really using char, use uint8_t.
Try this:
const uint8_t myByteArray[] = {
0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,
0x12,0x23,0x34,0x45,
0x56,0x67,0x78,0x89 };
size_t len = sizeof(myByteArray) / sizeof(uint8_t);
NSMutableString *myHexString = [NSMutableString stringWithCapacity:len * 2];
for (size_t i = 0; i < len; i++) {
[myHexString appendFormat:#"%02x", (int)myByteArray[i]];
}
Your initial byte data is char rather than unsigned char. This means that any values >127 (0x7f) will be seen as a twos-complement negative number, giving ffffffffffffff89.
If you change your data to be unsigned char you will get the desired result.
const unsigned char myByteArray[] = {
0x12,0x23,0x34,0x45,0x56,0x67,0x78,0x89,
0x12,0x23,0x34,0x45,
0x56,0x67,0x78,0x89 };
NSData *myByteData=[NSData dataWithBytes:myByteArray length:sizeof(myByteArray)];
NSMutableString *myHexString= [NSMutableString stringWithCapacity:myByteData.length*2];
for(int i=0;i<myByteData.length;i++){
NSString *resultString =[NSString stringWithFormat:#"%02lx",(unsigned long)myByteArray[i]];
[myHexString appendString:resultString];
}

Decrypting data, using aes gcm with the openssl evp interface in IOS

I've got the following code for decrypting the data:
-(NSString*)_decrypte:(NSString*)encrypted
{
NSString *decrypted;
NSData *enc = [[NSData alloc]initWithBase64EncodedString:encrypted options:0];
int len = (int)[enc length];
Byte *cipher = (Byte*)malloc(len);
memcpy((void *)cipher, [enc bytes], len);
Byte *iv = toIv(_ivCounter++, 16);
for(uint i = 0; i < 16; i++)
{
iv[i] = 0;
}
int outLen, plainttext_len, dec_success, tag_len = 128 / 8;
unsigned char *plaintext = (unsigned char*)malloc(len);
unsigned char *tag =(unsigned char*)malloc(tag_len);
int offset = len - (tag_len);
for(int i = 0; i < tag_len; i++)
{
tag[i] = cipher[i + offset];
}
EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new();
EVP_DecryptInit_ex(ctx, EVP_aes_128_gcm(), NULL, NULL, NULL);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_TAG, 16, (void *)tag);
EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_GCM_SET_IVLEN, 16, NULL);
EVP_DecryptInit_ex(ctx, NULL, NULL, _sesKey, iv);
EVP_DecryptUpdate(ctx, NULL, &len, NULL, 0);
EVP_DecryptUpdate(ctx, plaintext, &outLen, cipher, len);
plainttext_len = outLen;
dec_success = EVP_DecryptFinal_ex(ctx, plaintext + outLen, &outLen);
EVP_CIPHER_CTX_free(ctx);
decrypted = [NSString stringWithFormat:#"%s", plaintext];
return decrypted;
}
For some reason the code doesn't decrypt the data right. The _sesKey is right and the IV is overwritten after the call to toIV to force the right iv for the first set of data and there is no AAD data needed for the decrypting. I've already done this in android(using the bouncycastle library), so I known for a fact that the _sesKey and the IV are correct. I don't know if anybody can help me by telling what goes wrong and why.
I found the mistake with some help, the problem is that the variable _sesKey was a pointer and during generating the key and decrypting the data, the memory the pointer was pointing to got whiped. So the _sesKey became invalid. So now a changed _sesKey to a normal byte array and now it works.

Resources