¿Qué debo hacer al utilizar el cifrado openSSL en iOS?
En los últimos días, he estado luchando con el uso de RSA para el cifrado en iOS. No existe una API de cifrado RSA directo en iOS. Sin embargo, iOS proporciona la API x509 y x509 admite el cifrado RSA. Por lo tanto, podemos crear un certificado x509 autofirmado (debido a los bajos requisitos de seguridad, no necesitamos usar un certificado certificado por CA) y luego llamar a la API relevante de x509 para el cifrado. A continuación, registre todo el proceso.
El primer paso es crear un certificado autofirmado
1. La forma más sencilla y rápida es abrir Terminal y usar openssl (incluido con Mac OS X) para generar el certificado privado. clave y certificado autofirmado x509.
openssl req -x509 -out public_key.der -outform der -new -newkey rsa:1024 -keyout private_key.pem -days 3650
Simplemente ingrese el contenido de acuerdo con la línea de comando indicaciones.
Algunas notas:
public_key.der es el certificado x509 autofirmado de salida, que es lo que queremos usar.
private_key.pem es la clave privada de salida, que se utiliza para el descifrado. Consérvela correctamente.
rsa:1024 donde 1024 es la longitud de la clave, 1024 es relativamente segura. Si necesita más seguridad, puede usar 2048, pero los costos de cifrado y descifrado también aumentarán.
-días: tiempo de vencimiento del certificado, se debe agregar este parámetro. El tiempo de vencimiento predeterminado del certificado es 30 días. Generalmente, no queremos que el certificado caduque en tan poco tiempo, por lo que escribiremos uno más apropiado. número de días, por ejemplo aquí de 3650 (10 años).
De hecho, esta línea de comando contiene varios pasos (la razón por la que estudio los siguientes pasos es que ya tengo una clave privada private_key.pem a mano y quiero usarla directamente para generar una Certificado x509, es decir, se utilizan los siguientes 2-3)
1) Crear una clave privada
openssl genrsa -out private_key.pem 1024
2) Cree una solicitud de certificado (siga las indicaciones Ingrese información)
openssl req -new -out cert.csr -key private_key.pem
3) Certificado raíz autofirmado
openssl x509 -req -in cert.csr -out public_key.der -outform der -signkey private_key.pem -days 3650
2. Arrastre public_key.der a xcode. Si no hay ningún problema con el archivo, puede abrirlo directamente en xcode y ver información diversa sobre el certificado.
El segundo paso es utilizar public_key.der para el cifrado.
1. Importar marco de seguridad.
2. Coloque public_key.der en mainBundle (normalmente simplemente arrástrelo directamente a Xcode).
3. Lea la clave pública de public_key.der.
4.
El siguiente es un código de referencia (solo se puede utilizar para cifrar contenido menor o igual a 116 bytes de longitud, adecuado para cifrar contraseñas.
Se utiliza ARC, pero cabe señalar que algunos recursos deben liberarse mediante CFRealse)
RSA.h
//
// RSA.h
//
#import Foundation.h>
@interface RSA: NSObject {
SecKeyRef publicKey;
Certificado SecCertificateRef;
Política SecPolicyRef;
Confianza SecTrustRef;
size_t maxPlainLen;
}
- (NSData *) encryptWithData:(NSData *)contenido;
- (NSData *) encryptWithString:(NSString *)contenido;
@end
RSA .m
//
// RSA.m
//
#importar "RSA.h"
@implementation RSA
- (id)init {
self = [super init];
NSString *publicKeyPath = [[NSBundle mainBundle] pathForResource :@" public_key"
ofType:@"der"];
if (publicKeyPath == nil) {
NSLog(@"No se puede encontrar el pub .der" );
return nil;
}
NSDate *publicKeyFileContent = [NSData dataWithContentsOfFile:publicKeyPath];
if ( publicKeyFileContent == nil) {
NSLog(@"No se puede leer desde pub.der");
return nil;
}
certificado = SecCertificateCreateWithData(kCFAllocatorDefault, ( __bridge CFDataRef)publicKeyFileContent);
if (certificado == nil) {
NSLog(@"No se puede leer el certificado de pub.der" );
retorno nulo;
}
policy = SecPolicyCreateBasicX509();
OSStatus returnCode = SecTrustCreateWithCertificates(certificado, política y confianza );
if (returnCode != 0) {
NSLog(@"SecTrustCreateWithCertificates falla. Código de error: %ld", returnCode);
return nil ; p>
}
SecTrustResultType trustResultType;
>
returnCode = SecTrustEvaluate(trust, &trustResultType);
if (returnCode != 0) {
NSLog(@"SecTrustEvaluate falló. Código de error: %ld", returnCode );
devuelve nil;
}
publicKey = SecTrustCopyPublicKey(confianza);
if (publicKey == nil) {
NSLog(@"SecTrustCopyPublicKey fall");
devuelve nil;
}
maxPlainLen = SecKeyGetBlockSize(publicKey) - 12;
return self;
}
- (NSData *) encryptWithData:(NSData *)content {
size_t PlainLen = [longitud del contenido ];
if (plainLen > maxPlainLen) {
NSLog(@"content(%ld) es demasiado largo, debe < %ld", PlainLen, maxPlainLen);
devuelve nil;
}
void *plain = malloc(plainLen);
[content getBytes:plain
length:plainLen];
size_t cipherLen = 128; // La longitud actual de la clave RSA es 128 bytes
void *cipher = malloc(cipherLen);
OSStatus returnCode = SecKeyEncrypt(publicKey, kSecPaddingPKCS1, simple,
plainLen, cipher, &cipherLen);
NSData *resultado = nil;
if (returnCode != 0) {
NSLog(@"SecKeyEncrypt falló. Código de error: %ld", returnCode);
}
else {
resultado = [NSData dataWithBytes:cipher
length:cipherLen];
}
gratis(simple);
gratis (cifrado );
devolver resultado;
}
- (NSData *) encryptWithString:(NSString *)content {
return [self encryptWithData:[content dataUsingEncoding:NSUTF8StringEncoding]];
}
- (void)dealloc{
CFRelease(certificado);
CFRelease(confianza);
CFRelease(po
licy);
CFRelease(publicKey);
}
@end
Uso:
RSA * rsa = [[RSA alloc] init];
if (rsa != nil) {
NSLog(@"%@",[rsa encryptWithString:@"test"]) ;
}
else {
NSLog(@"init rsa error");
}