|
36 | 36 | import java.security.SecureRandom; |
37 | 37 | import java.util.Base64; |
38 | 38 |
|
| 39 | +/** |
| 40 | + * Implements PKCE using only the Java standard library. See https://www.rfc-editor.org/rfc/rfc7636. |
| 41 | + * |
| 42 | + * <p>https://developers.google.com/identity/protocols/oauth2/native-app#step1-code-verifier. |
| 43 | + */ |
39 | 44 | public class DefaultPKCEProvider implements PKCEProvider { |
40 | 45 | private String codeVerifier; |
41 | 46 | private CodeChallenge codeChallenge; |
42 | 47 | private static final int MAX_CODE_VERIFIER_LENGTH = 127; |
43 | 48 |
|
44 | | - private class CodeChallenge { |
45 | | - private String codeChallenge; |
46 | | - private String codeChallengeMethod; |
47 | | - |
48 | | - CodeChallenge(String codeVerifier) { |
49 | | - try { |
50 | | - byte[] bytes = codeVerifier.getBytes(); |
51 | | - MessageDigest md = MessageDigest.getInstance("SHA-256"); |
52 | | - md.update(bytes); |
53 | | - |
54 | | - byte[] digest = md.digest(); |
55 | | - |
56 | | - this.codeChallenge = Base64.getUrlEncoder().encodeToString(digest); |
57 | | - this.codeChallengeMethod = "S256"; |
58 | | - } catch (NoSuchAlgorithmException e) { |
59 | | - this.codeChallenge = codeVerifier; |
60 | | - this.codeChallengeMethod = "plain"; |
61 | | - } |
62 | | - } |
63 | | - |
64 | | - public String getCodeChallenge() { |
65 | | - return codeChallenge; |
66 | | - } |
67 | | - |
68 | | - public String getCodeChallengeMethod() { |
69 | | - return codeChallengeMethod; |
70 | | - } |
71 | | - } |
72 | | - |
73 | 49 | private String createCodeVerifier() { |
74 | 50 | SecureRandom sr = new SecureRandom(); |
75 | 51 | byte[] code = new byte[MAX_CODE_VERIFIER_LENGTH]; |
@@ -100,4 +76,34 @@ public String getCodeChallenge() { |
100 | 76 | public String getCodeChallengeMethod() { |
101 | 77 | return codeChallenge.getCodeChallengeMethod(); |
102 | 78 | } |
| 79 | + |
| 80 | + /** Class representing the Code Challenge derived from a Code Verifier string. */ |
| 81 | + private class CodeChallenge { |
| 82 | + private String codeChallenge; |
| 83 | + private String codeChallengeMethod; |
| 84 | + |
| 85 | + CodeChallenge(String codeVerifier) { |
| 86 | + try { |
| 87 | + byte[] bytes = codeVerifier.getBytes(); |
| 88 | + MessageDigest md = MessageDigest.getInstance("SHA-256"); |
| 89 | + md.update(bytes); |
| 90 | + |
| 91 | + byte[] digest = md.digest(); |
| 92 | + |
| 93 | + this.codeChallenge = Base64.getUrlEncoder().encodeToString(digest); |
| 94 | + this.codeChallengeMethod = "S256"; |
| 95 | + } catch (NoSuchAlgorithmException e) { |
| 96 | + this.codeChallenge = codeVerifier; |
| 97 | + this.codeChallengeMethod = "plain"; |
| 98 | + } |
| 99 | + } |
| 100 | + |
| 101 | + public String getCodeChallenge() { |
| 102 | + return codeChallenge; |
| 103 | + } |
| 104 | + |
| 105 | + public String getCodeChallengeMethod() { |
| 106 | + return codeChallengeMethod; |
| 107 | + } |
| 108 | + } |
103 | 109 | } |
0 commit comments