-
-
Save ateska/09e1c874494bba8e381ccd8d851b0df8 to your computer and use it in GitHub Desktop.
import binascii | |
import cryptography.hazmat.backends | |
import cryptography.hazmat.primitives.asymmetric.ec | |
import cryptography.hazmat.primitives.hashes | |
import cryptography.hazmat.primitives.kdf.x963kdf | |
import cryptography.hazmat.primitives.ciphers.aead | |
import cryptography.hazmat.primitives.serialization | |
# Alice (with iOS) is sending encrypted message to Bob (Python) | |
# | |
# This is based on https://darthnull.org/security/2018/05/31/secure-enclave-ecies/ | |
# It is a Proof-of-Concept that decrypts a ECEIS messages encrypted by iOS or macOS | |
# This piece is for SECP384R1 (be carefull, Secure Enclave can do only SECP256R1, which is only about changes in few parameters bellow) | |
# | |
# Swift code: | |
# var error : Unmanaged<CFError>? | |
# let request_cyphertext = SecKeyCreateEncryptedData( | |
# bob_public_key, | |
# SecKeyAlgorithm.eciesEncryptionCofactorX963SHA256AESGCM, | |
# request_plaintext as CFData, | |
# &error | |
# ) | |
# Ciphertext | |
ct = bytes.fromhex('046b935b6ac8236fdb8717ec8bc4c54275303ad2a48a02f6a58351985d8ed89793bc8c98261eb9bea5010d2f3d6ffe1e244698cfa8a61899905274796b192707012cdbb1b0be64389088b9499f61b110331c69e81e947756d687921510ae616863b5e26da3865c38fc37cd5a070007a54d0cabda5364618a289dca3eca07b271cc210964f67e8274b377944381f68818f84cdf75cb00ed38a0d1422a3b884612a90dddd8335db4b5bcd6642818f2c3b291dc4497c1e60fa51c97aba1bec2eba1d2af6f9b6d5f20e0e180a35399446addbd3944c3e512ff79e083609ddf234d37802c3ac2e2417e3e559cb6a2751851cc7844e7cd0b1cabd9de06910798f09814336eea473e0e6bf708f17ec0fd3949975597877c79a62402dcb37bd1466bcff11cafe0ea296229c4bfd2643616efdc40de7ce6e7adf5f3f50be572') | |
# Load the private key of the target (bob) | |
bob_pem = b''' | |
-----BEGIN EC PRIVATE KEY----- | |
MIG... private key lives here | |
-----END EC PRIVATE KEY-----''' | |
bob_private = cryptography.hazmat.primitives.serialization.load_pem_private_key( | |
bob_pem, | |
password=None, | |
backend=cryptography.hazmat.backends.default_backend() | |
) | |
# Extract the public key of the sender (ephemeral, only for this message) | |
alice_pub_bytes = ct[:96+1] | |
alice_public = cryptography.hazmat.primitives.asymmetric.ec.EllipticCurvePublicKey.from_encoded_point( | |
cryptography.hazmat.primitives.asymmetric.ec.SECP384R1(), | |
alice_pub_bytes | |
) | |
# | |
# use ECDH to generate a shared key using Alice's public and Bob's private keys | |
# | |
shared_key = bob_private.exchange( | |
cryptography.hazmat.primitives.asymmetric.ec.ECDH(), | |
alice_public | |
) | |
# # | |
# # Use the ANSI x9.63 Key Derivation Function to derive the final | |
# # encryption key from the ECDH-built key. | |
# # | |
# # * Use the SHA-256 hash when deriving the key, | |
# # * Use Alice's (ephemeral) public key data as Shared Info, and | |
# # * Extract 16 bytes (enough for a 128-bit key | |
xkdf = cryptography.hazmat.primitives.kdf.x963kdf.X963KDF( | |
algorithm=cryptography.hazmat.primitives.hashes.SHA256(), | |
length=32, | |
sharedinfo=alice_pub_bytes, | |
backend=cryptography.hazmat.backends.default_backend() | |
) | |
key_enc = xkdf.derive(shared_key) | |
iv = binascii.a2b_hex('00000000000000000000000000000000') | |
# # | |
# # DECRYPT THE MESSAGE! | |
# # | |
cryptor = cryptography.hazmat.primitives.ciphers.aead.AESGCM(key_enc) | |
pt = cryptor.decrypt(iv, ct[96+1:], b"") | |
print(pt) |
Thanks @ateska.
I have issue on this:
I get the publickey in order to encrypt in swift:
bob_pem = b'''
-----BEGIN EC PRIVATE KEY-----
MHQCAQEEIFL3sLnioGcDvHWM/BPlNw96BOx1KKco2qsq4UwhQUosoAcGBSuBBAAK
oUQDQgAEXs1Fmq4QdPAbn3NycdEU+HOjc3kW9efbso2kI/vdDTWcSCMk310s53G3
tRClDBPPuuJAsKghbPfaTaUpmXFCNA==
-----END EC PRIVATE KEY-----
'''bob_private = cryptography.hazmat.primitives.serialization.load_pem_private_key( bob_pem, password=None, backend=cryptography.hazmat.backends.default_backend() ) # Extract Bob's public key from his private key public_key = bob_private.public_key() # Extracting public key bytes public_key_bytes = public_key.public_bytes( encoding=cryptography.hazmat.primitives.serialization.Encoding.PEM, format=cryptography.hazmat.primitives.serialization.PublicFormat.SubjectPublicKeyInfo )
and in swift when ii try to encrypt since it is .pem it gives error:
let publicKey = """ -----BEGIN PUBLIC KEY----- MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEAs5xEIm001FFsRpXSRFEy57+swcr3nW9 SP3ERlrT539LE/x2auTwUVTCkaFS6R5IBl2QIvEml+UXgBU0sDK3PqZsqHcQzvBz Z/lX7NehqphbVCQBr3nkhDwyq0tkrmyD -----END PUBLIC KEY----- """ // Remove the header and footer let publicKeyString = publicKey.replacingOccurrences(of: "-----BEGIN PUBLIC KEY-----\n", with: "") .replacingOccurrences(of: "-----END PUBLIC KEY-----", with: "") .replacingOccurrences(of: "\n", with: "") // Decode the base64 string if let publicKeyData = Data(base64Encoded: publicKeyString) { print("What is base 64: \(publicKeyData.base64EncodedString())") } else { } let query: [String: Any] = [ kSecAttrKeyType as String: kSecAttrKeyTypeRSA, kSecAttrKeyClass as String: kSecAttrKeyClassPublic, kSecAttrKeySizeInBits as String: 2048 ] var unmanagedError: Unmanaged<CFError>? guard let pubKeyRef = SecKeyCreateWithData(pubKeyData as CFData, query as CFDictionary, &unmanagedError) else { print(unmanagedError!.takeRetainedValue() as Error) throw unmanagedError!.takeRetainedValue() as Error } print("What is pubref: \(pubKeyRef)") return pubKeyRef }
Any idea how to resolve this? do you have swift example class?
I have tried : https://github.com/agens-no/EllipticCurveKeyPair/tree/master with this example: https://darthnull.org/secure-enclave-ecies/ at the end I get error: Error: underlying(message: "Could not decrypt.", error: Error Domain=NSOSStatusErrorDomain Code=-50 "ECIES: Failed to aes-gcm decrypt data (err -69)" (paramErr: error in user parameter list) UserInfo={NSDescription=ECIES: Failed to aes-gcm decrypt data (err -69), numberOfErrorsDeep=0, NSLocalizedRecoverySuggestion=See https://www.osstatus.com/search/results?platform=all&framework=all&search=-50})
Sorry, I don't have a way to test it now.
Can confirm that for 100% but likely yes. @EasyAndComplex