2015-08-24 3 views
0

Мне нужна помощь в отношении некоторого шифрования в Swift. Я много искал шифрование RSA.Swift/Objective-C ASN1 encode public key

У нас есть сгенерированный открытый ключ от наших серверных серверов, и мы должны использовать этот ключ для шифрования секретного сообщения, которое снова будет передано на наши серверные серверы.

Я смог найти файлы шифрования RSA, но я боюсь, что у нас проблемы, потому что наш открытый ключ закодирован в ASN.1.

Обновления:

Ниже Вы наш фактический код. Мы попытались зашифровать сообщение, используя открытый ключ ASN.1 с нашего сервера. Проблема в том, что наши серверные серверы требуют, чтобы зашифрованный пароль был в шестнадцатеричном значении, хотя, я делаю это уже, однако наш бэкэнд не может расшифровать сообщение.

+ (SecKeyRef) setPublicKey: (NSString *) keyAsBase64 { 

/* First decode the Base64 string */ 
NSData * rawFormattedKey = base64_decode(keyAsBase64); 

/* Now strip the uncessary ASN encoding guff at the start */ 
unsigned char * bytes = (unsigned char *)[rawFormattedKey bytes]; 
size_t bytesLen = [rawFormattedKey length]; 

/* Strip the initial stuff */ 
size_t i = 0; 
if (bytes[i++] != 0x30) 
    return FALSE; 

/* Skip size bytes */ 
if (bytes[i] > 0x80) 
    i += bytes[i] - 0x80 + 1; 
else 
    i++; 

if (i >= bytesLen) 
    return FALSE; 

if (bytes[i] != 0x30) 
    return FALSE; 

/* Skip OID */ 
i += 15; 

if (i >= bytesLen - 2) 
    return FALSE; 

if (bytes[i++] != 0x03) 
    return FALSE; 

/* Skip length and null */ 
if (bytes[i] > 0x80) 
    i += bytes[i] - 0x80 + 1; 
else 
    i++; 

if (i >= bytesLen) 
    return FALSE; 

if (bytes[i++] != 0x00) 
    return FALSE; 

if (i >= bytesLen) 
    return FALSE; 

/* Here we go! */ 
NSData * extractedKey = [NSData dataWithBytes:&bytes[i] length:bytesLen - i]; 

/* Load as a key ref */ 
OSStatus error = noErr; 
CFTypeRef persistPeer = NULL; 

static const UInt8 publicKeyIdentifier[] = "com.our.key"; 
NSData * refTag = [[NSData alloc] initWithBytes:publicKeyIdentifier length:sizeof(publicKeyIdentifier)]; 

NSMutableDictionary * keyAttr = [[NSMutableDictionary alloc] init]; 

/* First we delete any current keys */ 
[keyAttr setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass]; 
[keyAttr setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 
[keyAttr setObject:refTag forKey:(__bridge id)kSecAttrApplicationTag]; 
error = SecItemDelete((__bridge CFDictionaryRef) keyAttr); 

[keyAttr setObject:extractedKey forKey:(__bridge id)kSecValueData]; 
[keyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnPersistentRef]; 
error = SecItemAdd((__bridge CFDictionaryRef) keyAttr, (CFTypeRef *)&persistPeer); 

CFRelease(persistPeer); 

/* Now we extract the real ref */ 
SecKeyRef publicKeyRef = nil; 

[keyAttr removeAllObjects]; 
[keyAttr setObject:(__bridge id)kSecClassKey forKey:(__bridge id)kSecClass]; 
[keyAttr setObject:refTag forKey:(__bridge id)kSecAttrApplicationTag]; 
[keyAttr setObject:(__bridge id)kSecAttrKeyTypeRSA forKey:(__bridge id)kSecAttrKeyType]; 
[keyAttr setObject:[NSNumber numberWithBool:YES] forKey:(__bridge id)kSecReturnRef]; 

// Get the persistent key reference. 
error = SecItemCopyMatching((__bridge CFDictionaryRef)keyAttr, (CFTypeRef *)&publicKeyRef); 

if (publicKeyRef == nil || (error != noErr && error != errSecDuplicateItem)) { 
    NSLog(@"Error retrieving public key reference from chain"); 
    return FALSE; 
} 


return publicKeyRef; 
} 


+(NSString*)encryptWithPublicKey:(NSString*)key input:(NSString*) input { 
const size_t BUFFER_SIZE =  16; 
const size_t CIPHER_BUFFER_SIZE = 16; 
const uint32_t PKCS1 = kSecPaddingPKCS1; 

SecKeyRef publicKey = [self setPublicKey:key]; 

NSData *crypted = nil; 
NSData *rawinput = [input dataUsingEncoding:NSUTF8StringEncoding]; 
NSString *theInput = [self base64forData:rawinput]; 
NSData *data = [theInput dataUsingEncoding:NSUTF8StringEncoding]; 

uint8_t *srcbuf; 
srcbuf = (uint8_t *)calloc(BUFFER_SIZE, sizeof(uint8_t)); 
srcbuf = (uint8_t *)[data bytes]; 

size_t srclen = (size_t)data.length; 
size_t outlen = SecKeyGetBlockSize(publicKey) * sizeof(uint8_t); 
void *outbuf = malloc(outlen); 

OSStatus status = noErr; 
status = SecKeyEncrypt(publicKey, 
         PKCS1, 
         srcbuf, 
         srclen, 
         outbuf, 
         &outlen); 

if (status != 0) { 
    //NSLog(@"SecKeyEncrypt fail. Error Code: %ld", status); 
}else{ 
    crypted = [NSData dataWithBytes:outbuf length:outlen]; 
} 

NSString *str = [crypted stringWithHexBytes2]; 

free(outbuf); 
CFRelease(publicKey); 
return str; 
} 

Это категория для преобразования гексагона NSData.

- (NSString*)stringWithHexBytes2 { 
static const char hexdigits[] = "abcdef"; 
const size_t numBytes = [self length]; 
const unsigned char* bytes = [self bytes]; 
char *strbuf = (char *)malloc(numBytes * 2 + 1); 
char *hex = strbuf; 
NSString *hexBytes = nil; 

for (int i = 0; i<numBytes; ++i) { 
    const unsigned char c = *bytes++; 
    *hex++ = hexdigits[(c >> 4) & 0xF]; 
    *hex++ = hexdigits[(c) & 0xF]; 
} 
*hex = 0; 
hexBytes = [NSString stringWithUTF8String:strbuf]; 
free(strbuf); 
return hexBytes; 
} 
+0

Что это библиотека javascipt? это открытый источник? – Shripada

+0

Вы видели [эти библиотеки] (https://developer.apple.com/library/mac/documentation/Security/Conceptual/cryptoservices/GeneralPurposeCrypto/GeneralPurposeCrypto.html)? – jtbandes

+0

@Shripada: Мы используем наши собственные библиотеки. – pdoy

ответ

0

Проблема не в шифровании. Однако из-за соображений безопасности и политики компании нам требуется несколько шагов и уровней шифрования, прежде чем сервер сможет успешно расшифровать пароль.

Большое спасибо за усилия по оказанию мне помощи.

Кстати, код выше работает отлично, хотя он не включает в себя наш дополнительный уровень шифрования.