Created
March 10, 2026 19:55
-
-
Save LethalMaus/80e7745011748f291e517333deeeb8a4 to your computer and use it in GitHub Desktop.
Secure ECDH key agreement and derived session key example
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| override fun performEcdhKeyAgreement(serverEcPublicKeyPem: String): CryptoHelper.EcdhInfo { | |
| // Minimal ECDH example with P-256; expects a PEM-encoded X.509 SubjectPublicKeyInfo | |
| val pem = serverEcPublicKeyPem | |
| .replace("-----BEGIN PUBLIC KEY-----", "") | |
| .replace("-----END PUBLIC KEY-----", "") | |
| .replace("\n", "") | |
| .trim() | |
| val serverPub = Base64.decode(pem, Base64.DEFAULT) | |
| val kf = KeyFactory.getInstance("EC") | |
| val pubKey = kf.generatePublic(X509EncodedKeySpec(serverPub)) | |
| val ka = KeyAgreement.getInstance("ECDH") | |
| val keyPair = java.security.KeyPairGenerator.getInstance("EC").apply { | |
| initialize(256, random) | |
| }.genKeyPair() | |
| ka.init(keyPair.private) | |
| ka.doPhase(pubKey, true) | |
| val shared = ka.generateSecret() | |
| // Derive AES key via PBKDF2 (HKDF would be better; using PBKDF2 here to avoid extra deps) | |
| val salt = ByteArray(16).also { random.nextBytes(it) } | |
| val skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256") | |
| val key = skf.generateSecret(PBEKeySpec(Base64.encodeToString(shared, Base64.NO_WRAP).toCharArray(), salt, 10_000, 256)) | |
| val derived = SecretKeySpec(key.encoded, "AES") | |
| symmetricKey = derived | |
| return CryptoHelper.EcdhInfo( | |
| publicKeyPem = exportPublicKeyPem(keyPair.public.encoded), | |
| sharedSecretBytes = shared.size, | |
| derivedKeyBytes = derived.encoded.size | |
| ) | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment