From 5a3daf48469c336405e88843488d52f24311a862 Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Wed, 19 Mar 2014 15:25:50 -0700 Subject: [PATCH] Curve25519 keys to 1 mod 8 for ephemerals. --- library/jni/curve25519-donna-jni.c | 7 ++++++- library/jni/curve25519-donna.c | 3 --- library/libs/armeabi-v7a/libcurve25519.so | Bin 17532 -> 17532 bytes library/libs/armeabi/libcurve25519.so | Bin 21624 -> 21624 bytes library/libs/x86/libcurve25519.so | Bin 17488 -> 17488 bytes .../textsecure/crypto/PreKeyUtil.java | 4 ++-- .../textsecure/crypto/SessionCipherV2.java | 2 +- .../textsecure/crypto/ecc/Curve.java | 10 +++++----- .../textsecure/crypto/ecc/Curve25519.java | 10 +++++----- .../crypto/ratchet/RatchetingSession.java | 2 +- .../textsecure/storage/LocalKeyRecord.java | 2 +- .../crypto/AsymmetricMasterCipher.java | 2 +- .../securesms/crypto/IdentityKeyUtil.java | 6 +++--- .../crypto/KeyExchangeInitiator.java | 4 ++-- .../crypto/KeyExchangeProcessorV1.java | 4 ++-- .../crypto/KeyExchangeProcessorV2.java | 8 ++++---- .../securesms/crypto/MasterSecretUtil.java | 2 +- 17 files changed, 34 insertions(+), 32 deletions(-) diff --git a/library/jni/curve25519-donna-jni.c b/library/jni/curve25519-donna-jni.c index bcda8a4a5a..4ce32bb632 100644 --- a/library/jni/curve25519-donna-jni.c +++ b/library/jni/curve25519-donna-jni.c @@ -22,11 +22,16 @@ #include "curve25519-donna.h" JNIEXPORT jbyteArray JNICALL Java_org_whispersystems_textsecure_crypto_ecc_Curve25519_generatePrivateKey - (JNIEnv *env, jclass clazz, jbyteArray random) + (JNIEnv *env, jclass clazz, jbyteArray random, jboolean ephemeral) { uint8_t* privateKey = (uint8_t*)(*env)->GetByteArrayElements(env, random, 0); privateKey[0] &= 248; + + if (ephemeral) { + privateKey[0] |= 1; + } + privateKey[31] &= 127; privateKey[31] |= 64; diff --git a/library/jni/curve25519-donna.c b/library/jni/curve25519-donna.c index bb1262e5e9..b84c9e0ff1 100644 --- a/library/jni/curve25519-donna.c +++ b/library/jni/curve25519-donna.c @@ -720,9 +720,6 @@ curve25519_donna(u8 *mypublic, const u8 *secret, const u8 *basepoint) { int i; for (i = 0; i < 32; ++i) e[i] = secret[i]; - e[0] &= 248; - e[31] &= 127; - e[31] |= 64; fexpand(bp, basepoint); cmult(x, z, e, bp); diff --git a/library/libs/armeabi-v7a/libcurve25519.so b/library/libs/armeabi-v7a/libcurve25519.so index 16f42b116a4ddbaad674aa2dd81cef2afcb8e16c..3fa1b15aa8b334258988015469018f1a5a10caf6 100755 GIT binary patch delta 2456 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 diff --git a/library/libs/armeabi/libcurve25519.so b/library/libs/armeabi/libcurve25519.so index 4c019bead8cf4d4245d82cbb0aa9e22db9943b96..f109b7eb4a35cdfb5bbb574e041ee6da89126053 100755 GIT binary patch delta 4747 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 delta 4792 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 diff --git a/library/libs/x86/libcurve25519.so b/library/libs/x86/libcurve25519.so index bc0779fc229125073a96e50d6e24bf99dbc2e5bc..bb80ed1ea8d5277b013c6a5ede59c0662d115665 100755 GIT binary patch delta 3137 zcma)9ZERCj7{1-wt!0B=ut34G6*#aBhihRZBUb2eKS~_Z#c5_RX6k}N2N|&#z$G0p zwAa#DJToCt6NoHg+>epX24ck(6ciz;d12QlD%a;d_X33_h9>1b=Q+=L z&ig*+VWWAtHw?8xEQxvON(jP} z_a-g1uc!huSm5M;7R;Cr)()^>oDTuZ)Z`<_PHN)=9Y3ZfR*nGJqhsJy=4GT%8J>n* zP4LhMu`ZB67>SfBU~L8EnL2MpB|a*WvROGQia`v>sq=EQmicT0VES#hYy%>16yrSt z!~-2WWI^5QO!YZ!Cv5xeowsw=!DV>U!**dUal^0|eHcQX=Md-<>%pnzEmj&G7SZKNwZ4-$`TUcWh383&+XoCRzrAQSE!{mC@*NEs>o~UAVgISE!0UiA+MjKCIj#lhjXX3JRjU z6f=vpF)~(75{%5y7k)YzdLFfdL=4KQ%lFz}Ulnblswo{8?GE5ZLT-^ztX=30cFeyc zGuSUy3K%P?kI)kBA`3vYZEEWu0wP5~6$CBkL(CPH^mN2hHvY9@J5sUr|*_Ux=tt?3+@`)K4fqwAEvmjK)`2G)+;F;>jn$Qx}1- zdkoz7_CmaP@QZIMe=$k1x1exCT2_6-Ox?dOm=5A3$T)!xtR+XQnS-aN6@;IM7)e11 zrTIy)yAS%8ux4FslR%VwrrrifkUB?CqfT{UChDW}LkBLXl;1l)y;Og#IH`4+_zvLd z1{U7X$y$-IDa4mgw}u<<9BRnbq5aV3`r>c@Xj+`^4g~3v(;tlHx%!2-Z+s1-u_RM5 z0OcUv2;)!!Eyfcg)@$)G5A6nAAPg?h8=)>is({3MVH|^i4$+YSOB{nad`*!n?7Wf5 zr3EDmeY4&KIb`-*q2f9LWwH61jv8+6TjF z;S8F=YPydlHoiyS=5nSk))zO9gDBB=A73n90%#At6sQrvq`P*E9?reZyNX>?`UmMu z-Er+GU6pp>ARr;x%YQE(KX%9Pfe$b9Gc(5WvJ%^(RSluC7Qg&Yj$@<9t7`NIySZGT!mS@PPy$Dw*tQzb0lFuY;&&ozBfnYXzV^UU(Mo z4$K%~$vJpT)0W2h%VkbpU*kPkk6-1x@vtp>IpQK}l{ z4!mOyyqmpnV^&tfDD!s*_A|irYibv-^h~wT-}Yv{3@tMr+(y3HQ)nqhE5yG)jAL%W!bfOjHbG>DjKD18r6fJr(x- zt7$UUiT|W&tI%KBCkZoGc=PW3+Y%PT>Sr_`||~#nf?RONw~5A delta 3037 zcmZWre{54#6n4M(>0=BM1 zl5Q7j<7d&&nmgY&%r%z3_(Hm#-AKilC)LcnDU009OmY<)tY%iAB(*i0BT4q|h`Yse zhmV;U1H4GSv-#Ci>8?eDK>xJ-3M-dm%%|*8Rdx5N%e>mW*|3ctFz>P+m>`dFZRbKu zV{z`XYt&2eeI@IkO|aAqNor|l+hFeO$;Jm0Y#%Y=NmjFX%Q_Yh+PiBR4YX^1WD?3r zX2eW;_j-eWy#JDw7nBx1Z13J_v7Ov~2?-dn222c@{Hncu&?;xxUd)yU{3CFh?d>NW zJm?Pc*3!IjT&PLhxPNvr#nvL#hy(?p# z=zfi&5FUHSgaru~?!HRmfohgtg{*QH>%llJY8b=#O+l^xOHN&81CT`!w+|qU&y@#g znUwLM6+?6MMFx3?C$B;mdI(tTN_VJOlUp9p(N1lpSfK43BJvvdJbusPc^9q&i7Wk|WA_pu`513dM!k zt7sWwV{KXixoHPTXWE0~bOdY@B>m)8=<>@7$(rtEEjT}#vJf;2xH;Xy8m;`%`L)(7 z=+eWJ^P}-}m#9;H3h2B?i;#K};~u=X4yF^#X~co+Vuvj-y{rjm9JnYlioxs9yjhd* zM&NCLm*N8(*1SQ=9^NBF)XS0vf%VC~ES^9Rj96`AJW}$UTdzv z4(EyKjR1L&Y6}?X)@V(~7NI0?hEXxWK84N^!c&>_fuu<`u@ugj(sol-Q_ZXisJfH` zRVlBci$_3}H+h6P;{gG*Tvk;*Tl53+UF1vYDkT^ILpT+~UKGJ|>!2X3WjmZ736q+HgL*^034qMt^Iu<_wdq1B{Q8km@aTSQ|p+EhZmK`KPFKyg$gCX zf;92(EO@SiGMfHCc;tMhJgtR`DsNpE;i5`CW+G#%iUx`=i+>}nD6Ehj{uq%=_1{E_ z!}Tn_r-QX1GehjLwSd&o;!$t}4}da?b`)(o1XRg%_DQk`{1nOue~_0ho)?crQ`*VX z<%`<86Q-^BpQ1k|V%Av&6S3$F0g51)!6ul&h`ta0$S>RffhN67L5BL6PcK?{y*Q^L zM;y?{X}6#r`O*n-&Xt$2M7Ze8!zJqE8O=p)xI~#$@xzN<@!~(HV(GS!ix?);4WZoq zLkx;LM4xp{+bm)L5p5QBh`_W%Uuk&Z)$yPG4=-|Q*IXi(@{U@#w0dc1gB@qPdweQHXf0_%G@p@RH(jnxI7oSK6CH3imzP=RSsk{E{R z^P`XN^er%7L92;>f>u6m<3|3a&u#Xh)y&7yszocw3;h*l`a8<-r~He}U1&x54)_$b zuJD6sxo{dB{Cocjb1houd12);a{{d>4^^&-SKU)p2jUE!QPoDYts|=13hRZ9z^;Qm z0vm-r4ch~I6L#;ns_Mi?Y7bTwgjHbcVV&QpY7#d3ldAT@hH-l-uvT2bE_^&Rz(&YI z&7`W@R3|pO2ae9d6+g`2o)u4Y-gq)>G=%vhtKH_h3VdzxO{*8!TF|0*h`$5B_;&C7 IboC*_zrTo#i~s-t diff --git a/library/src/org/whispersystems/textsecure/crypto/PreKeyUtil.java b/library/src/org/whispersystems/textsecure/crypto/PreKeyUtil.java index 146ade1078..e137b97c09 100644 --- a/library/src/org/whispersystems/textsecure/crypto/PreKeyUtil.java +++ b/library/src/org/whispersystems/textsecure/crypto/PreKeyUtil.java @@ -48,7 +48,7 @@ public class PreKeyUtil { for (int i=0;i receiverChain = rootKey.createChain(theirEphemeral, ourEphemeral); - ECKeyPair ourNewEphemeral = Curve.generateKeyPairForType(Curve.DJB_TYPE); + ECKeyPair ourNewEphemeral = Curve.generateKeyPairForType(Curve.DJB_TYPE, true); Pair senderChain = receiverChain.first.createChain(theirEphemeral, ourNewEphemeral); sessionState.setRootKey(senderChain.first); diff --git a/library/src/org/whispersystems/textsecure/crypto/ecc/Curve.java b/library/src/org/whispersystems/textsecure/crypto/ecc/Curve.java index aa9381969a..097d6930a2 100644 --- a/library/src/org/whispersystems/textsecure/crypto/ecc/Curve.java +++ b/library/src/org/whispersystems/textsecure/crypto/ecc/Curve.java @@ -25,9 +25,9 @@ public class Curve { private static final int NIST_TYPE2 = 0x03; public static final int DJB_TYPE = 0x05; - public static ECKeyPair generateKeyPairForType(int keyType) { + public static ECKeyPair generateKeyPairForType(int keyType, boolean ephemeral) { if (keyType == DJB_TYPE) { - return Curve25519.generateKeyPair(); + return Curve25519.generateKeyPair(ephemeral); } else if (keyType == NIST_TYPE || keyType == NIST_TYPE2) { return CurveP256.generateKeyPair(); } else { @@ -35,11 +35,11 @@ public class Curve { } } - public static ECKeyPair generateKeyPairForSession(int messageVersion) { + public static ECKeyPair generateKeyPairForSession(int messageVersion, boolean ephemeral) { if (messageVersion <= CiphertextMessage.LEGACY_VERSION) { - return generateKeyPairForType(NIST_TYPE); + return generateKeyPairForType(NIST_TYPE, ephemeral); } else { - return generateKeyPairForType(DJB_TYPE); + return generateKeyPairForType(DJB_TYPE, ephemeral); } } diff --git a/library/src/org/whispersystems/textsecure/crypto/ecc/Curve25519.java b/library/src/org/whispersystems/textsecure/crypto/ecc/Curve25519.java index 64dc5e7b27..94bd71b67d 100644 --- a/library/src/org/whispersystems/textsecure/crypto/ecc/Curve25519.java +++ b/library/src/org/whispersystems/textsecure/crypto/ecc/Curve25519.java @@ -37,10 +37,10 @@ public class Curve25519 { private static native byte[] calculateAgreement(byte[] ourPrivate, byte[] theirPublic); private static native byte[] generatePublicKey(byte[] privateKey); - private static native byte[] generatePrivateKey(byte[] random); + private static native byte[] generatePrivateKey(byte[] random, boolean ephemeral); - public static ECKeyPair generateKeyPair() { - byte[] privateKey = generatePrivateKey(); + public static ECKeyPair generateKeyPair(boolean ephemeral) { + byte[] privateKey = generatePrivateKey(ephemeral); byte[] publicKey = generatePublicKey(privateKey); return new ECKeyPair(new DjbECPublicKey(publicKey), new DjbECPrivateKey(privateKey)); @@ -65,11 +65,11 @@ public class Curve25519 { return new DjbECPublicKey(keyBytes); } - private static byte[] generatePrivateKey() { + private static byte[] generatePrivateKey(boolean ephemeral) { byte[] privateKey = new byte[32]; random.nextBytes(privateKey); - return generatePrivateKey(privateKey); + return generatePrivateKey(privateKey, ephemeral); } } diff --git a/library/src/org/whispersystems/textsecure/crypto/ratchet/RatchetingSession.java b/library/src/org/whispersystems/textsecure/crypto/ratchet/RatchetingSession.java index 924b163935..a7f716bacd 100644 --- a/library/src/org/whispersystems/textsecure/crypto/ratchet/RatchetingSession.java +++ b/library/src/org/whispersystems/textsecure/crypto/ratchet/RatchetingSession.java @@ -45,7 +45,7 @@ public class RatchetingSession { sessionState.setRemoteIdentityKey(theirIdentityKey); sessionState.setLocalIdentityKey(ourIdentityKey.getPublicKey()); - ECKeyPair sendingKey = Curve.generateKeyPairForType(ourIdentityKey.getPublicKey().getPublicKey().getType()); + ECKeyPair sendingKey = Curve.generateKeyPairForType(ourIdentityKey.getPublicKey().getPublicKey().getType(), true); Pair receivingChain = calculate3DHE(true, ourBaseKey, theirBaseKey, ourIdentityKey, theirIdentityKey); Pair sendingChain = receivingChain.first.createChain(theirEphemeralKey, sendingKey); diff --git a/library/src/org/whispersystems/textsecure/storage/LocalKeyRecord.java b/library/src/org/whispersystems/textsecure/storage/LocalKeyRecord.java index 97810179a7..3f1aafd070 100644 --- a/library/src/org/whispersystems/textsecure/storage/LocalKeyRecord.java +++ b/library/src/org/whispersystems/textsecure/storage/LocalKeyRecord.java @@ -70,7 +70,7 @@ public class LocalKeyRecord extends Record { this.localCurrentKeyPair = this.localNextKeyPair; this.localNextKeyPair = new KeyPair((this.localNextKeyPair.getId()+1) % Medium.MAX_VALUE, - Curve.generateKeyPairForType(keyType), + Curve.generateKeyPairForType(keyType, true), masterSecret); } } diff --git a/src/org/thoughtcrime/securesms/crypto/AsymmetricMasterCipher.java b/src/org/thoughtcrime/securesms/crypto/AsymmetricMasterCipher.java index 4c6588a664..1b521e114b 100644 --- a/src/org/thoughtcrime/securesms/crypto/AsymmetricMasterCipher.java +++ b/src/org/thoughtcrime/securesms/crypto/AsymmetricMasterCipher.java @@ -93,7 +93,7 @@ public class AsymmetricMasterCipher { theirPublic = asymmetricMasterSecret.getNistPublicKey(); } - ECKeyPair ourKeyPair = Curve.generateKeyPairForType(theirPublic.getType()); + ECKeyPair ourKeyPair = Curve.generateKeyPairForType(theirPublic.getType(), true); byte[] secret = Curve.calculateAgreement(theirPublic, ourKeyPair.getPrivateKey()); MasterCipher masterCipher = getMasterCipherForSecret(secret); byte[] encryptedBodyBytes = masterCipher.encryptBytes(body.getBytes()); diff --git a/src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java b/src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java index d7bf6da1eb..ed63b477c4 100644 --- a/src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java +++ b/src/org/thoughtcrime/securesms/crypto/IdentityKeyUtil.java @@ -135,8 +135,8 @@ public class IdentityKeyUtil { } public static void generateIdentityKeys(Context context, MasterSecret masterSecret) { - ECKeyPair nistKeyPair = Curve.generateKeyPairForType(Curve.NIST_TYPE); - ECKeyPair djbKeyPair = Curve.generateKeyPairForType(Curve.DJB_TYPE); + ECKeyPair nistKeyPair = Curve.generateKeyPairForType(Curve.NIST_TYPE, false); + ECKeyPair djbKeyPair = Curve.generateKeyPairForType(Curve.DJB_TYPE, false); MasterCipher masterCipher = new MasterCipher(masterSecret); IdentityKey nistIdentityKey = new IdentityKey(nistKeyPair.getPublicKey()); @@ -160,7 +160,7 @@ public class IdentityKeyUtil { public static void generateCurve25519IdentityKeys(Context context, MasterSecret masterSecret) { MasterCipher masterCipher = new MasterCipher(masterSecret); - ECKeyPair djbKeyPair = Curve.generateKeyPairForType(Curve.DJB_TYPE); + ECKeyPair djbKeyPair = Curve.generateKeyPairForType(Curve.DJB_TYPE, false); IdentityKey djbIdentityKey = new IdentityKey(djbKeyPair.getPublicKey()); byte[] djbPrivateKey = masterCipher.encryptKey(djbKeyPair.getPrivateKey()); diff --git a/src/org/thoughtcrime/securesms/crypto/KeyExchangeInitiator.java b/src/org/thoughtcrime/securesms/crypto/KeyExchangeInitiator.java index e6e697427a..3bb1ac9a19 100644 --- a/src/org/thoughtcrime/securesms/crypto/KeyExchangeInitiator.java +++ b/src/org/thoughtcrime/securesms/crypto/KeyExchangeInitiator.java @@ -62,8 +62,8 @@ public class KeyExchangeInitiator { private static void initiateKeyExchange(Context context, MasterSecret masterSecret, Recipient recipient) { int sequence = getRandomSequence(); int flags = KeyExchangeMessageV2.INITIATE_FLAG; - ECKeyPair baseKey = Curve.generateKeyPairForSession(CiphertextMessage.CURRENT_VERSION); - ECKeyPair ephemeralKey = Curve.generateKeyPairForSession(CiphertextMessage.CURRENT_VERSION); + ECKeyPair baseKey = Curve.generateKeyPairForSession(CiphertextMessage.CURRENT_VERSION, true); + ECKeyPair ephemeralKey = Curve.generateKeyPairForSession(CiphertextMessage.CURRENT_VERSION, true); IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context, masterSecret, Curve.DJB_TYPE); KeyExchangeMessageV2 message = new KeyExchangeMessageV2(sequence, flags, diff --git a/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV1.java b/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV1.java index d0219407c0..44367f6a4a 100644 --- a/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV1.java +++ b/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV1.java @@ -136,8 +136,8 @@ public class KeyExchangeProcessorV1 extends KeyExchangeProcessor { SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG"); int initialId = secureRandom.nextInt(4094) + 1; - KeyPair currentPair = new KeyPair(initialId, Curve.generateKeyPairForSession(1), masterSecret); - KeyPair nextPair = new KeyPair(initialId + 1, Curve.generateKeyPairForSession(1), masterSecret); + KeyPair currentPair = new KeyPair(initialId, Curve.generateKeyPairForSession(1, true), masterSecret); + KeyPair nextPair = new KeyPair(initialId + 1, Curve.generateKeyPairForSession(1, true), masterSecret); LocalKeyRecord record = new LocalKeyRecord(context, masterSecret, recipient); record.setCurrentKeyPair(currentPair); diff --git a/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV2.java b/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV2.java index 2bbf886a82..c09b05f067 100644 --- a/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV2.java +++ b/src/org/thoughtcrime/securesms/crypto/KeyExchangeProcessorV2.java @@ -131,8 +131,8 @@ public class KeyExchangeProcessorV2 extends KeyExchangeProcessor { public void processKeyExchangeMessage(PreKeyEntity message, long threadId) throws InvalidKeyException { - ECKeyPair ourBaseKey = Curve.generateKeyPairForSession(2); - ECKeyPair ourEphemeralKey = Curve.generateKeyPairForSession(2); + ECKeyPair ourBaseKey = Curve.generateKeyPairForSession(2, true); + ECKeyPair ourEphemeralKey = Curve.generateKeyPairForSession(2, true); ECPublicKey theirBaseKey = message.getPublicKey(); ECPublicKey theirEphemeralKey = theirBaseKey; IdentityKey theirIdentityKey = message.getIdentityKey(); @@ -184,8 +184,8 @@ public class KeyExchangeProcessorV2 extends KeyExchangeProcessor { if (!sessionRecord.getSessionState().hasPendingKeyExchange()) { Log.w("KeyExchangeProcessorV2", "We don't have a pending initiate..."); - ourBaseKey = Curve.generateKeyPairForType(message.getBaseKey().getType()); - ourEphemeralKey = Curve.generateKeyPairForType(message.getBaseKey().getType()); + ourBaseKey = Curve.generateKeyPairForType(message.getBaseKey().getType(), true); + ourEphemeralKey = Curve.generateKeyPairForType(message.getBaseKey().getType(), true); ourIdentityKey = IdentityKeyUtil.getIdentityKeyPair(context, masterSecret, message.getBaseKey().getType()); sessionRecord.getSessionState().setPendingKeyExchange(message.getSequence(), ourBaseKey, diff --git a/src/org/thoughtcrime/securesms/crypto/MasterSecretUtil.java b/src/org/thoughtcrime/securesms/crypto/MasterSecretUtil.java index 146925a8c9..d1803344f3 100644 --- a/src/org/thoughtcrime/securesms/crypto/MasterSecretUtil.java +++ b/src/org/thoughtcrime/securesms/crypto/MasterSecretUtil.java @@ -160,7 +160,7 @@ public class MasterSecretUtil { MasterSecret masterSecret) { MasterCipher masterCipher = new MasterCipher(masterSecret); - ECKeyPair keyPair = Curve.generateKeyPairForType(Curve.DJB_TYPE); + ECKeyPair keyPair = Curve.generateKeyPairForType(Curve.DJB_TYPE, true); save(context, ASYMMETRIC_LOCAL_PUBLIC_DJB, keyPair.getPublicKey().serialize()); save(context, ASYMMETRIC_LOCAL_PRIVATE_DJB, masterCipher.encryptKey(keyPair.getPrivateKey()));