55import org .apache .logging .log4j .Logger ;
66import org .bouncycastle .crypto .Digest ;
77import org .bouncycastle .crypto .digests .SHA256Digest ;
8- import org .bouncycastle .util .encoders .UrlBase64 ;
98
109import java .nio .charset .StandardCharsets ;
10+ import java .security .SecureRandom ;
1111import java .text .MessageFormat ;
12+ import java .util .Base64 ;
1213
1314@ SuppressWarnings ("LoggingSimilarMessage" )
1415public class Pkce {
@@ -17,28 +18,29 @@ public class Pkce {
1718
1819 public static String create (int len , String option ) {
1920 logger .trace ("create" );
20- String code_verifier = Random .alphanumeric (len );
21+ byte [] code_verifier_bytes = getRandomBytes (len );
22+ String code_verifier = Base64 .getUrlEncoder ().withoutPadding ().encodeToString (code_verifier_bytes );
2123 switch (option .toUpperCase ().trim ()) {
2224 case "S256" :
23- byte [] digest = hash (new SHA256Digest (), code_verifier .getBytes (StandardCharsets .UTF_8 ));
24- return MessageFormat .format ("{0},{1}" , code_verifier . trim (), new String ( UrlBase64 . encode (digest ) ));
25+ byte [] digest = hash (new SHA256Digest (), code_verifier .getBytes (StandardCharsets .US_ASCII ));
26+ return MessageFormat .format ("{0},{1}" , code_verifier , Base64 . getUrlEncoder (). withoutPadding (). encodeToString (digest ));
2527 case "PLAIN" :
26- return MessageFormat .format ("{0},{1}" , code_verifier . trim (), Encoding . toBase64Url ( code_verifier . trim ()) );
28+ return MessageFormat .format ("{0},{1}" , code_verifier , code_verifier );
2729 default :
2830 logger .error ("Unknown PKCE option" );
2931 return "" ;
3032 }
33+
3134 }
3235
3336 public static boolean verify (String code_verifier , String code_challenge , String option ) {
3437 logger .trace ("verify" );
3538 switch (option .toUpperCase ().trim ()) {
3639 case "S256" :
37- byte [] digest = hash (new SHA256Digest (), code_verifier .trim ().getBytes (StandardCharsets .UTF_8 ));
38- return ( new String ( UrlBase64 . encode (digest )) ).equals (code_challenge .trim ());
40+ byte [] digest = hash (new SHA256Digest (), code_verifier .trim ().getBytes (StandardCharsets .US_ASCII ));
41+ return Base64 . getUrlEncoder (). withoutPadding (). encodeToString (digest ).equals (code_challenge .trim ());
3942 case "PLAIN" :
40- byte [] bytes_plain = UrlBase64 .decode (code_challenge .trim ().getBytes (StandardCharsets .UTF_8 ));
41- return new String (bytes_plain ).equals (code_verifier .trim ());
43+ return code_challenge .trim ().equals (code_verifier .trim ());
4244 default :
4345 logger .error ("Unknown PKCE option" );
4446 return false ;
@@ -51,4 +53,12 @@ private static byte[] hash(Digest digest, byte[] inputBytes) {
5153 digest .doFinal (retValue , 0 );
5254 return retValue ;
5355 }
56+
57+ private static byte [] getRandomBytes (int len ) {
58+ logger .trace ("getRandomBytes" );
59+ SecureRandom secureRandom = new SecureRandom ();
60+ byte [] bytes = new byte [len ];
61+ secureRandom .nextBytes (bytes );
62+ return bytes ;
63+ }
5464}
0 commit comments