Мне нужна помощь в отношении некоторого шифрования в 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;
}
Что это библиотека javascipt? это открытый источник? – Shripada
Вы видели [эти библиотеки] (https://developer.apple.com/library/mac/documentation/Security/Conceptual/cryptoservices/GeneralPurposeCrypto/GeneralPurposeCrypto.html)? – jtbandes
@Shripada: Мы используем наши собственные библиотеки. – pdoy