Ich versuche eine Zeichenfolge in einem AES-128 GCM-Format in Ziel c zu verschlüsseln/entschlüsseln. Ich habe überall gesucht, aber ich finde keine funktionierende Lösung.AES 128 GCM Objektiv C osx
Antwort
Vor nicht allzu langer Zeit hatte ich ein ähnliches Problem und die beste Antwort, die ich finden konnte, war this one. Zusammengefasst, iOS hat einige Funktionen, um zu tun, was Sie wollen, aber sie sind privat.
Also, bis Apple entscheidet, diese Funktionen freizugeben, entschied ich mich für die Entwicklung meiner eigenen Bibliothek, derzeit in GitHub gespeichert und in CocoaPods verfügbar.
Der Fall, dass Sie beschreiben könnte auf diese Weise realisiert werden:
#import <CommonCrypto/CommonCrypto.h>
#import "IAGAesGcm.h"
// For the case you describe, the key length is 128 bits (16 bytes)
u_char keyBytes[kCCKeySizeAES128] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10};
NSData *key = [NSData dataWithBytes:keyBytes length:sizeof(keyBytes)];
// GCM recommends a IV size of 96 bits (12 bytes), but you are free
// to use other sizes
u_char ivBytes[12] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C};
NSData *iv = [NSData dataWithBytes:ivBytes length:sizeof(ivBytes)];
NSData *aad = [@"AdditionalAuthenticatedData" dataUsingEncoding:NSUTF8StringEncoding];
// Authenticated Encryption Function
NSData *expectedPlainData = [@"PlainData" dataUsingEncoding:NSUTF8StringEncoding];
// The returned ciphered data is a simple class with 2 properties: the actual encrypted data and the authentication tag.
// The authentication tag can have multiple sizes and it is up to you to set one, in this case the size is 128 bits
// (16 bytes)
IAGCipheredData *cipheredData = [IAGAesGcm cipheredDataByAuthenticatedEncryptingPlainData:expectedPlainData
withAdditionalAuthenticatedData:aad
authenticationTagLength:IAGAuthenticationTagLength128
initializationVector:iv
key:key
error:nil];
// Authenticated Decryption Function
NSData *plainData = [IAGAesGcm plainDataByAuthenticatedDecryptingCipheredData:cipheredData
withAdditionalAuthenticatedData:aad
initializationVector:iv
key:key
error:nil];
XCTAssertEqualObjects(expectedPlainData, plainData);
Hoffnung dieser Code eine Hilfe ist.
zu beenden (und dank zaph dies für die Erwähnung), habe ich eine Benchmarking dieses Codes nicht durchgeführt, so davon ausgehen, dass es langsam ist. Ich beabsichtige, es zu benutzen, um Token in einer JWE Schnur zu entschlüsseln und nur von Zeit zu Zeit, ich empfehle nicht irgendetwas, das mehr als das erfordert.
Grüße.
/*
typical GCM use case: sending an authenticated packet
+--------------+-------+--------------+
| header | seq. | Data |
+--------------+-------+--------------+
| | |
| | |
Addtl auth data IV plain text
| | |
| | V
| | +--------------------+
| +---->| |
| | | GCM encryption |
+---------------->| |
| | +--------------------+
| | | |
| | cipher text Auth tag
| | | |
V V V V
+--------------+-------+----------------+---------+
| header | seq. | encrypted data | ICV |
+--------------+-------+----------------+---------+
*/
#define CCCryptorGCMprologue() CCCryptor *cryptor = getRealCryptor(cryptorRef, 0); \
CC_DEBUG_LOG("Entering\n"); \
if(!cryptor) return kCCParamError;
static inline CCCryptorStatus translate_err_code(int err)
{
if (err==0) {
return kCCSuccess;
} /*else if(err == CCMODE_INVALID_CALL_SEQUENCE){ //unti we can read error codes from corecrypto
return kCCCallSequenceError;
} */ else {
return kCCUnspecifiedError;
}
}
CCCryptorStatus
CCCryptorGCMAddIV(CCCryptorRef cryptorRef,
const void *iv,
size_t ivLen)
{
CCCryptorGCMprologue();
if(ivLen!=0 && iv==NULL) return kCCParamError;
//it is okay to call with ivLen 0 and/OR iv==NULL
//infact this needs to be done even with NULL values, otherwise ccgcm_ is going to return call sequence error.
//currently corecrypto accepts NULL
//rdar://problem/23523093
int rc = ccgcm_set_iv_legacy(cryptor->symMode[cryptor->op].gcm,cryptor->ctx[cryptor->op].gcm, ivLen, iv);
return translate_err_code(rc);
}
//Add additional authentication data
CCCryptorStatus
CCCryptorGCMAddAAD(CCCryptorRef cryptorRef,
const void *aData,
size_t aDataLen)
{
CCCryptorGCMprologue();
if(aDataLen!=0 && aData==NULL) return kCCParamError;
//it is okay to call with aData zero
int rc = ccgcm_gmac(cryptor->symMode[cryptor->op].gcm,cryptor->ctx[cryptor->op].gcm, aDataLen, aData);
return translate_err_code(rc);
}
// This is for old iOS5 clients
CCCryptorStatus
CCCryptorGCMAddADD(CCCryptorRef cryptorRef,
const void *aData,
size_t aDataLen)
{
return CCCryptorGCMAddAAD(cryptorRef, aData, aDataLen);
}
// This was a temp mistake in MacOSX8
CCCryptorStatus
CCCryptorGCMaddAAD(CCCryptorRef cryptorRef,
const void *aData,
size_t aDataLen)
{
return CCCryptorGCMAddAAD(cryptorRef, aData, aDataLen);
}
//we are not providing this function to users.
//The reason is that we don't want to create more liability for ourself
//and a new interface function just increases the number of APIs
//without actually helping users
//User's use the old CCCryptorGCMEncrypt() and CCCryptorGCMDecrypt()
static CCCryptorStatus gcm_update(CCCryptorRef cryptorRef,
const void *dataIn,
size_t dataInLength,
void *dataOut)
{
CCCryptorGCMprologue();
if(dataInLength!=0 && dataIn==NULL) return kCCParamError;
//no data is okay
if(dataOut == NULL) return kCCParamError;
int rc = ccgcm_update(cryptor->symMode[cryptor->op].gcm,cryptor->ctx[cryptor->op].gcm, dataInLength, dataIn, dataOut);
return translate_err_code(rc);
}
CCCryptorStatus CCCryptorGCMEncrypt(CCCryptorRef cryptorRef,
const void *dataIn,
size_t dataInLength,
void *dataOut)
{
return gcm_update(cryptorRef, dataIn, dataInLength, dataOut);
}
CCCryptorStatus CCCryptorGCMDecrypt(CCCryptorRef cryptorRef,
const void *dataIn,
size_t dataInLength,
void *dataOut)
{
return gcm_update(cryptorRef, dataIn, dataInLength, dataOut);
}
CCCryptorStatus CCCryptorGCMFinal(CCCryptorRef cryptorRef,
void *tagOut,
size_t *tagLength)
{
CCCryptorGCMprologue();
if(tagOut == NULL || tagLength == NULL) return kCCParamError;
int rc = ccgcm_finalize(cryptor->symMode[cryptor->op].gcm,cryptor->ctx[cryptor->op].gcm, *tagLength, (void *) tagOut);
if(rc == -1)
return kCCUnspecifiedError;
else
return kCCSuccess; //this includes 0 and any error message other than -1
// ccgcm_finalize() returns CCMODE_INTEGRITY_FAILURE (-3) if the expected tag is not coppied to the buffer. but that doesn't mean there is an error
}
CCCryptorStatus CCCryptorGCMReset(CCCryptorRef cryptorRef)
{
CCCryptorGCMprologue();
int rc = ccgcm_reset(cryptor->symMode[cryptor->op].gcm,cryptor->ctx[cryptor->op].gcm);
return translate_err_code(rc);
}
CCCryptorStatus CCCryptorGCM(CCOperation op, /* kCCEncrypt, kCCDecrypt */
CCAlgorithm alg,
const void *key, size_t keyLength, /* raw key material */
const void *iv, size_t ivLen,
const void *aData, size_t aDataLen,
const void *dataIn, size_t dataInLength,
void *dataOut,
void *tagOut, size_t *tagLength)
{
CCCryptorRef cryptorRef;
CCCryptorStatus retval;
CC_DEBUG_LOG("Entering Op: %d Cipher: %d\n", op, alg);
retval = CCCryptorCreateWithMode(op, kCCModeGCM, alg, 0, NULL, key, keyLength,
NULL, 0, 0, 0, &cryptorRef);
if(retval) return retval;
//call even with NULL pointer and zero length IV
retval = CCCryptorGCMAddIV(cryptorRef, iv, ivLen);
if(retval) return retval;
retval = CCCryptorGCMaddAAD(cryptorRef, aData, aDataLen);
if(retval) return retval;
retval = gcm_update(cryptorRef, dataIn, dataInLength, dataOut);
if(retval) return retval;
retval = CCCryptorGCMFinal(cryptorRef, tagOut, tagLength);
CCCryptorRelease(cryptorRef);
return retval;
}
- 1. Android AES 128 Verschlüsselung
- 2. AES-128-Verschlüsselung mit WinCrypt
- 3. AES (aes-cbc-128, aes-cbc-192, aes-cbc-256) Verschlüsselung/Entschlüsselung mit openssl C
- 4. AES (aes-ige-128, aes-ige-192, aes-ige-256) Verschlüsselung/Entschlüsselung mit openssl C
- 5. Ungültige AES-Schlüssellänge: 128 Bytes?
- 6. Rubin - nicht unterstützte Verschlüsselungsalgorithmus (AES-256-GCM)
- 7. Gibt es einen Unterschied zwischen AES-128-CBC und AES-128-Verschlüsselung?
- 8. Android Cipher AES/GCM/NoPadding "iv == null"
- 9. "Nicht unterstützten Zustand oder nicht authentifizieren Daten" mit AES-128-Gcm in Knoten
- 10. Downgrade Spring Security zu AES-128
- 11. Wie sichere HLS Videos, mit AES 128
- 12. S-Box in AES CCM 128 bit
- 13. AES 128 DOT NET und Java-Kompatibilität
- 14. AES 128 mit CBC In IOS
- 15. C# AES Entschlüsselung - Mac Check-in GCM fehlgeschlagen
- 16. korrekte nonce/iv Größe für AES-GCM-Modus
- 17. AES GCM Verschlüsselung und Entschlüsselung in JAVA
- 18. Wie kann ich AES 128 ohne IV verschlüsseln und entschlüsseln?
- 19. Durchschlagsschrift in Objektiv C
- 20. Circular UILabel Objektiv C
- 21. AES Decrypting C#
- 22. AES-Verschlüsselung und C#
- 23. Wie ein AES Cipher mit einem 128-Bit-Kette erstellen enthält 128 0en
- 24. AES 128-Verschlüsselung in Java Entschlüsselung in PHP
- 25. Warum erweitert die AES 128-Verschlüsselung die Daten?
- 26. Was ist falsch an dieser AES 128-Verschlüsselung?
- 27. aes ctr 128-Bit-Entschlüsselung in Embedded-System
- 28. AES-Verschlüsselung: InvalidKeyException: Schlüssellänge nicht 128/192/256 Bits
- 29. JAVA - Verschlüsseln eines Textes mit Windows-Benutzernamen in AES 128
- 30. Wie man ein AES-128-verschlüsseltes HLS-Video in AVPlayer
Beachten Sie, dass das Apple AES-GCM etwas hirntot ist, es behandelt keine damit verbundenen Daten. Selbst Apple gibt zu, dass es sich um eine schlechte Implementierung handelt, die nur ihren Anforderungen entspricht. Übrigens, haben Sie irgendwelche Benchmarks? – zaph
Ich war mir dessen nicht bewusst, vielen Dank für die Informationen. Nun, es war eine _learning_ Erfahrung :). Über die Leistung habe ich [dieses Dokument] (http://csrc.nist.gov/groups/ST/toolkit/BCM/documents/proposedmodes/gcm/gcm-spec.pdf) im Repo verlinkt, es weist auf einen effizienten auf Weg, diesen Algorithmus zu implementieren ... was nicht die Art war, wie ich es kodierte, war ich mehr daran interessiert, einen Code zu schreiben, der leicht zu debuggen ist. Also muss die Leistung _nicht toll_ sein. – Enrique
Gute Arbeit, der Code sieht gut aus. Unglücklicherweise ist es für mich nur eine Arbeit, die ich ausgeben möchte. Die ganze podfile Sache würde mich eine Stunde oder so dauern, um herauszufinden und alles aktualisiert zu bekommen. – zaph