介绍
已经建立了称为PKCE(RFC 7636)的规范,作为针对使用OAuth进行授权代码窃取攻击的对策,该规范是在客户端生成称为Code_Verifier和Code_Challenge的代码并将其嵌入请求参数中的规范。
由于已决定在开发与PKCE兼容的API服务时使用JMeter进行负载测试,并将客户端的代码生成过程并入JMeter,因此将说明当时合并的方法和过程。
生成Code_Verifier和Code_Challenge
为了使用JMeter生成要嵌入到请求中的代码(Code_Verifier,Code_Challenge),请生成一个包含代码生成类的jar。
由于代码生成算法在RFC 7636中的定义如下,因此请实现一个根据规范生成代码的Java程序。
code_verifier =使用的高熵密码随机STRING
保留字符[A-Z] / [a-z] / [0-9] /"-" /"。" /" _" /"?"
[RFC3986]第2.3节中的内容,最小长度为43个字符。
且最大长度为128个字符。
省略了
code_challenge = BASE64URL-ENCODE(SHA256(ASCII(code_verifier)))
省略了
"代码挑战"的ABNF如下。
代码挑战= 43 * 128未保留
未保留= ALPHA / DIGIT /"-" /"。" /" _" /"?"
ALPHA =%x41-5A /%x61-7A
数字=%x30-39
将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package com.sample.pkce; import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.lang3.RandomStringUtils; import java.util.Base64; public class PKCECode { private final String CODE_VERFIER_STRING = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-._~"; public String getCodeVerifier(final int codeVerifierLength) { return RandomStringUtils.random(codeVerifierLength, CODE_VERFIER_STRING); } public String getCodeChallenge(final String codeVerifier) { final byte[] hashedCodeVerifier = DigestUtils.sha256(codeVerifier); final String base64EncodedCodeVerifier = Base64.getEncoder().encodeToString(hashedCodeVerifier); final String base64URLEncodedCodeVerifier = base64EncodedCodeVerifier .replaceAll("=","") .replaceAll("\\+","-") .replaceAll("/","_"); return base64URLEncodedCodeVerifier; } } |
为了确认所实现的程序是否可以正确生成Code_Challenge,我们使用与RFC 7636附录转换示例相同的CodeVerifier进行了测试,并确认转换成功。
1 2 3 4 5 6 | @Test public void getCodeChallengeTest() { final String codeVerifier = "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"; final PKCECode pkceCode = new PKCECode(); Assert.assertEquals("E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM", pkceCode.getCodeChallenge(codeVerifier)); } |
使用JMeter要求
启动JMeter之前,将使用的库
之后,启动JMeter,从"添加"和"预处理"中选择
1 2 3 4 5 6 7 8 | import com.sample.pkce.PKCECode PKCECode pkceCode = new PKCECode(); String codeVerifier = pkceCode.getCodeVerifier(43); //Code_Verifierの文字長を指定する String codeChallenge= pkceCode.getCodeChallenge(codeVerifier); vars.put("codeVerifier",codeVerifier ); vars.put("codeChallenge",codeChallenge); |
之后,使用HTTP请求的request参数中的
补品376??9111
这次,我解释了如何将代码生成过程合并到
- 如何预先将大量代码输出到CSV文件并使用JMeter的``
-
在所有请求的JMeter参数中直接将Code_Verifier和Code_Challenge设置为固定值
- 如果可以接受固定值,则也可以使用RFC 7636附录转换示例,而不必费心生成新代码。
参考
有关为什么它是43到128个字符的说明,我在这里详细说明。请参考。
- https://techblog.yahoo.co.jp/entry/20191219790463/