22
33import org .bouncycastle .bcpg .PublicKeyAlgorithmTags ;
44import org .bouncycastle .bcpg .PublicKeyPacket ;
5+ import org .bouncycastle .bcpg .SymmetricKeyAlgorithmTags ;
56import org .bouncycastle .bcpg .X25519PublicBCPGKey ;
67import org .bouncycastle .bcpg .X25519SecretBCPGKey ;
78import org .bouncycastle .crypto .AsymmetricCipherKeyPair ;
89import org .bouncycastle .crypto .generators .X25519KeyPairGenerator ;
910import org .bouncycastle .crypto .params .X25519KeyGenerationParameters ;
1011import org .bouncycastle .jcajce .spec .XDHParameterSpec ;
1112import org .bouncycastle .jce .provider .BouncyCastleProvider ;
12- import org .bouncycastle .openpgp .PGPException ;
13+ import org .bouncycastle .openpgp .*;
14+ import org .bouncycastle .openpgp .bc .BcPGPObjectFactory ;
15+ import org .bouncycastle .openpgp .jcajce .JcaPGPObjectFactory ;
16+ import org .bouncycastle .openpgp .operator .PGPDataEncryptorBuilder ;
17+ import org .bouncycastle .openpgp .operator .PublicKeyDataDecryptorFactory ;
18+ import org .bouncycastle .openpgp .operator .PublicKeyKeyEncryptionMethodGenerator ;
19+ import org .bouncycastle .openpgp .operator .bc .BcPGPDataEncryptorBuilder ;
1320import org .bouncycastle .openpgp .operator .bc .BcPGPKeyPair ;
21+ import org .bouncycastle .openpgp .operator .bc .BcPublicKeyDataDecryptorFactory ;
22+ import org .bouncycastle .openpgp .operator .bc .BcPublicKeyKeyEncryptionMethodGenerator ;
1423import org .bouncycastle .openpgp .operator .jcajce .JcaPGPKeyPair ;
15-
16- import java .io .IOException ;
24+ import org .bouncycastle .openpgp .operator .jcajce .JcePGPDataEncryptorBuilder ;
25+ import org .bouncycastle .openpgp .operator .jcajce .JcePublicKeyDataDecryptorFactoryBuilder ;
26+ import org .bouncycastle .openpgp .operator .jcajce .JcePublicKeyKeyEncryptionMethodGenerator ;
27+ import org .bouncycastle .util .Arrays ;
28+ import org .bouncycastle .util .io .Streams ;
29+
30+ import java .io .*;
31+ import java .nio .charset .StandardCharsets ;
1732import java .security .*;
1833import java .util .Date ;
1934
@@ -32,6 +47,8 @@ public void performTest()
3247 {
3348 testConversionOfJcaKeyPair ();
3449 testConversionOfBcKeyPair ();
50+ testV4MessageEncryptionDecryptionWithJcaKey ();
51+ testV4MessageEncryptionDecryptionWithBcKey ();
3552 }
3653
3754 private void testConversionOfJcaKeyPair ()
@@ -128,6 +145,96 @@ private void testConversionOfBcKeyPair()
128145 }
129146 }
130147
148+ private void testV4MessageEncryptionDecryptionWithJcaKey ()
149+ throws PGPException , NoSuchAlgorithmException , InvalidAlgorithmParameterException , IOException
150+ {
151+ BouncyCastleProvider provider = new BouncyCastleProvider ();
152+
153+ Date date = currentTimeRounded ();
154+ KeyPairGenerator gen = KeyPairGenerator .getInstance ("XDH" , provider );
155+ gen .initialize (new XDHParameterSpec ("X25519" ));
156+ KeyPair kp = gen .generateKeyPair ();
157+ PGPKeyPair keyPair = new JcaPGPKeyPair (PublicKeyAlgorithmTags .X25519 , kp , date );
158+
159+ byte [] data = "Hello, World!\n " .getBytes (StandardCharsets .UTF_8 );
160+
161+ PGPDataEncryptorBuilder encBuilder = new JcePGPDataEncryptorBuilder (SymmetricKeyAlgorithmTags .AES_256 )
162+ .setProvider (provider );
163+ PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator (encBuilder );
164+ PublicKeyKeyEncryptionMethodGenerator metGen = new JcePublicKeyKeyEncryptionMethodGenerator (keyPair .getPublicKey ())
165+ .setProvider (provider );
166+ encGen .addMethod (metGen );
167+ PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator ();
168+
169+ ByteArrayOutputStream bOut = new ByteArrayOutputStream ();
170+ OutputStream encOut = encGen .open (bOut , new byte [4096 ]);
171+ OutputStream litOut = litGen .open (encOut , PGPLiteralData .BINARY , "" , PGPLiteralData .NOW , new byte [4096 ]);
172+ litOut .write (data );
173+ litGen .close ();
174+ encGen .close ();
175+
176+ byte [] encrypted = bOut .toByteArray ();
177+
178+ ByteArrayInputStream bIn = new ByteArrayInputStream (encrypted );
179+ PGPObjectFactory objectFactory = new JcaPGPObjectFactory (bIn );
180+ PGPEncryptedDataList encDataList = (PGPEncryptedDataList ) objectFactory .nextObject ();
181+ PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData ) encDataList .get (0 );
182+ PublicKeyDataDecryptorFactory decFactory = new JcePublicKeyDataDecryptorFactoryBuilder ()
183+ .setProvider (provider )
184+ .build (keyPair .getPrivateKey ());
185+ InputStream decIn = encData .getDataStream (decFactory );
186+ objectFactory = new JcaPGPObjectFactory (decIn );
187+ PGPLiteralData lit = (PGPLiteralData ) objectFactory .nextObject ();
188+ InputStream litIn = lit .getDataStream ();
189+ byte [] plaintext = Streams .readAll (litIn );
190+ litIn .close ();
191+ decIn .close ();
192+
193+ isTrue (Arrays .areEqual (data , plaintext ));
194+ }
195+
196+ private void testV4MessageEncryptionDecryptionWithBcKey ()
197+ throws PGPException , IOException
198+ {
199+ Date date = currentTimeRounded ();
200+ X25519KeyPairGenerator gen = new X25519KeyPairGenerator ();
201+ gen .init (new X25519KeyGenerationParameters (new SecureRandom ()));
202+ AsymmetricCipherKeyPair kp = gen .generateKeyPair ();
203+ BcPGPKeyPair keyPair = new BcPGPKeyPair (PublicKeyAlgorithmTags .X25519 , kp , date );
204+
205+ byte [] data = "Hello, World!\n " .getBytes (StandardCharsets .UTF_8 );
206+
207+ PGPDataEncryptorBuilder encBuilder = new BcPGPDataEncryptorBuilder (SymmetricKeyAlgorithmTags .AES_256 );
208+ PGPEncryptedDataGenerator encGen = new PGPEncryptedDataGenerator (encBuilder );
209+ PublicKeyKeyEncryptionMethodGenerator metGen = new BcPublicKeyKeyEncryptionMethodGenerator (keyPair .getPublicKey ());
210+ encGen .addMethod (metGen );
211+ PGPLiteralDataGenerator litGen = new PGPLiteralDataGenerator ();
212+
213+ ByteArrayOutputStream bOut = new ByteArrayOutputStream ();
214+ OutputStream encOut = encGen .open (bOut , new byte [4096 ]);
215+ OutputStream litOut = litGen .open (encOut , PGPLiteralData .BINARY , "" , PGPLiteralData .NOW , new byte [4096 ]);
216+ litOut .write (data );
217+ litGen .close ();
218+ encGen .close ();
219+
220+ byte [] encrypted = bOut .toByteArray ();
221+
222+ ByteArrayInputStream bIn = new ByteArrayInputStream (encrypted );
223+ PGPObjectFactory objectFactory = new BcPGPObjectFactory (bIn );
224+ PGPEncryptedDataList encDataList = (PGPEncryptedDataList ) objectFactory .nextObject ();
225+ PGPPublicKeyEncryptedData encData = (PGPPublicKeyEncryptedData ) encDataList .get (0 );
226+ PublicKeyDataDecryptorFactory decFactory = new BcPublicKeyDataDecryptorFactory (keyPair .getPrivateKey ());
227+ InputStream decIn = encData .getDataStream (decFactory );
228+ objectFactory = new BcPGPObjectFactory (decIn );
229+ PGPLiteralData lit = (PGPLiteralData ) objectFactory .nextObject ();
230+ InputStream litIn = lit .getDataStream ();
231+ byte [] plaintext = Streams .readAll (litIn );
232+ litIn .close ();
233+ decIn .close ();
234+
235+ isTrue (Arrays .areEqual (data , plaintext ));
236+ }
237+
131238 public static void main (String [] args )
132239 {
133240 runTest (new DedicatedX25519KeyPairTest ());
0 commit comments