1
+ using System ;
1
2
using System . Security ;
3
+ using System . Security . Cryptography ;
4
+ using System . Text ;
5
+ using System . Web ;
2
6
using GeneXus ;
3
7
using log4net ;
4
8
using Org . BouncyCastle . Crypto ;
@@ -16,14 +20,15 @@ public class Pkce
16
20
internal static string Create ( int len , string option )
17
21
{
18
22
logger . Trace ( "Create" ) ;
19
- string code_verifier = Random . Alphanumeric ( len ) ;
23
+ byte [ ] code_verifier_bytes = GetRandomBytes ( len ) ;
24
+ string code_verifier = System . Text . Encoding . UTF8 . GetString ( UrlBase64 . Encode ( code_verifier_bytes ) ) ;
20
25
switch ( option . ToUpper ( ) . Trim ( ) )
21
26
{
22
27
case "S256" :
23
- byte [ ] digest = Hash ( new Sha256Digest ( ) , System . Text . Encoding . UTF8 . GetBytes ( code_verifier . Trim ( ) ) ) ;
24
- return $ "{ code_verifier . Trim ( ) } ,{ System . Text . Encoding . UTF8 . GetString ( UrlBase64 . Encode ( digest ) ) } ";
28
+ byte [ ] digest = Hash ( new Sha256Digest ( ) , System . Text . Encoding . ASCII . GetBytes ( code_verifier ) ) ;
29
+ return $ "{ code_verifier } ,{ Jose . Base64Url . Encode ( digest ) } ";
25
30
case "PLAIN" :
26
- return $ "{ code_verifier . Trim ( ) } ,{ Encoding . ToBase64Url ( code_verifier . Trim ( ) ) } ";
31
+ return $ "{ code_verifier } ,{ code_verifier } ";
27
32
default :
28
33
logger . Error ( "Unknown PKCE option" ) ;
29
34
return "" ;
@@ -37,11 +42,10 @@ public static bool Verify(string code_verifier, string code_challenge, string op
37
42
switch ( option . ToUpper ( ) . Trim ( ) )
38
43
{
39
44
case "S256" :
40
- byte [ ] digest = Hash ( new Sha256Digest ( ) , System . Text . Encoding . UTF8 . GetBytes ( code_verifier . Trim ( ) ) ) ;
41
- return System . Text . Encoding . UTF8 . GetString ( UrlBase64 . Encode ( digest ) ) . Equals ( code_challenge . Trim ( ) ) ;
45
+ byte [ ] digest = Hash ( new Sha256Digest ( ) , System . Text . Encoding . ASCII . GetBytes ( code_verifier ) ) ;
46
+ return Jose . Base64Url . Encode ( digest ) . Equals ( code_challenge . Trim ( ) ) ;
42
47
case "PLAIN" :
43
- byte [ ] bytes_plain = UrlBase64 . Decode ( System . Text . Encoding . UTF8 . GetBytes ( code_challenge . Trim ( ) ) ) ;
44
- return System . Text . Encoding . UTF8 . GetString ( bytes_plain ) . Equals ( code_verifier . Trim ( ) ) ;
48
+ return code_challenge . Trim ( ) . Equals ( code_verifier . Trim ( ) ) ;
45
49
default :
46
50
logger . Error ( "Unknown PKCE option" ) ;
47
51
return false ;
@@ -55,5 +59,18 @@ private static byte[] Hash(IDigest digest, byte[] inputBytes)
55
59
digest . DoFinal ( retValue , 0 ) ;
56
60
return retValue ;
57
61
}
62
+
63
+ private static byte [ ] GetRandomBytes ( int len )
64
+ {
65
+ byte [ ] data = new byte [ len ] ;
66
+ #if NETCORE
67
+ var arraySpan = new Span < byte > ( data ) ;
68
+ System . Security . Cryptography . RandomNumberGenerator . Fill ( arraySpan ) ;
69
+ #else
70
+ RNGCryptoServiceProvider crypto = new RNGCryptoServiceProvider ( ) ;
71
+ crypto . GetBytes ( data ) ;
72
+ #endif
73
+ return data ;
74
+ }
58
75
}
59
76
}
0 commit comments