Wie signieren und verifizieren Sie einige Daten auf iOS mit einem RSA-Schlüssel (vorzugsweise mit dem System eigenen libcommonCrypto
)?Signieren und Verifizieren unter iOS mit RSA
Antwort
Da in StackOverflow und den Apple-Dokumenten bisher kaum Wissen zum Signieren und Verifizieren gefunden wurde, musste ich manuell in den iOS-Header-Dateien suchen und SecKeyRawSign
und SecKeyRawVerify
finden. Die folgenden Codezeilen scheinen zu funktionieren.
Signing NSData (unter Verwendung von SHA256 mit RSA):
NSData* PKCSSignBytesSHA256withRSA(NSData* plainData, SecKeyRef privateKey)
{
size_t signedHashBytesSize = SecKeyGetBlockSize(privateKey);
uint8_t* signedHashBytes = malloc(signedHashBytesSize);
memset(signedHashBytes, 0x0, signedHashBytesSize);
size_t hashBytesSize = CC_SHA256_DIGEST_LENGTH;
uint8_t* hashBytes = malloc(hashBytesSize);
if (!CC_SHA256([plainData bytes], (CC_LONG)[plainData length], hashBytes)) {
return nil;
}
SecKeyRawSign(privateKey,
kSecPaddingPKCS1SHA256,
hashBytes,
hashBytesSize,
signedHashBytes,
&signedHashBytesSize);
NSData* signedHash = [NSData dataWithBytes:signedHashBytes
length:(NSUInteger)signedHashBytesSize];
if (hashBytes)
free(hashBytes);
if (signedHashBytes)
free(signedHashBytes);
return signedHash;
}
Verification (unter Verwendung von SHA256 mit RSA):
BOOL PKCSVerifyBytesSHA256withRSA(NSData* plainData, NSData* signature, SecKeyRef publicKey)
{
size_t signedHashBytesSize = SecKeyGetBlockSize(publicKey);
const void* signedHashBytes = [signature bytes];
size_t hashBytesSize = CC_SHA256_DIGEST_LENGTH;
uint8_t* hashBytes = malloc(hashBytesSize);
if (!CC_SHA256([plainData bytes], (CC_LONG)[plainData length], hashBytes)) {
return nil;
}
OSStatus status = SecKeyRawVerify(publicKey,
kSecPaddingPKCS1SHA256,
hashBytes,
hashBytesSize,
signedHashBytes,
signedHashBytesSize);
return status == errSecSuccess;
}
Alternativen (OpenSSL):
Es gibt eine sehr gute Alternative, die OpenSSL direkt anstelle von libCommonCrypto verwendet. MIHCrypto ist eine gut entworfene Objective-C-Wrapper-Bibliothek für OpenSSL, die das Arbeiten mit Kryptografie sehr einfach macht. Siehe das Beispiel unten.
einen Schlüssel generieren einfach ist das:
MIHAESKeyFactory *factory = [[MIHAESKeyFactory alloc] init];
id<MIHSymmetricKey> aesKey = [factory generateKey];
Oder einen Schlüssel aus Datei laden:
NSData *privateKeyData = [[NSFileManager defaultManager] contentsAtPath:"mykey.pem"];
MIHRSAPrivateKey *privateKey = [[MIHRSAPrivateKey alloc] initWithData:privateKeyData];
Jetzt etwas unterschreiben:
NSError *signingError = nil;
NSData *message = // load something to sign from somewhere
NSData *signature = [privateKey signWithSHA256:message error:&signingError]
Weitere Beispiele durchsuchen Sie die MIHCrypto Seite .
Wäre schön, ein ähnliches Beispiel für "SecKeyRawSign" und "SecKeyRawVerify" in ** Swift ** zu haben. Wenn jemand das geschafft hat, bitte hier verlinken/einfügen. Werde das Gleiche tun, wenn ich es funktioniere. – stannie
Irgendwas Glück? Ich brauche wirklich Hilfe! http://stackoverflow.com/questions/32759385/swift-rsa-encrypt-a-string-with-a-specific-private-key –
Vergessen Sie nicht
Wo befinden sich die RSA-Schlüssel (Plural wegen öffentlicher und privater Teile zum Verifizieren und Signieren)? Sind sie im Schlüsselbund oder sind sie extern im PEM- oder DER-Format? – jww
Wie in der Frage beschrieben, würde ich lieber libcommonCrypto verwenden. Dies bedeutet, dass der Schlüssel außerhalb der Programmieransicht als "SecKeyRef" verfügbar ist (in der Speicherreferenz, die von Schlüsselbund, PEM oder irgendetwas anderem stammen kann, das von Apple Security Framework unterstützt wird). Die Art des Schlüssels sollte für meine Frage keine Rolle spielen, aber im Moment speichere ich alle Schlüssel (eigenen privaten Schlüssel und einige öffentliche Schlüssel) im Sandkasten Schlüsselbund. – miho
Versuchen Sie, einige Daten mithilfe von RSA mit öffentlichen/privaten Schlüsseln zu verschlüsseln/zu entschlüsseln? – jailani