parent
c94e013ded
commit
5ff3e8867b
@ -0,0 +1,70 @@ |
||||
/* |
||||
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
||||
* 项目名称:Java 信息安全性设计准则 |
||||
* 项目描述:用于检查Java源代码的安全性设计准则的Sonarqube插件 |
||||
* 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
||||
*/ |
||||
package com.keyware.sonar.java.rules.checkers; |
||||
|
||||
import org.sonar.check.Rule; |
||||
import org.sonar.java.ast.parser.ArgumentListTreeImpl; |
||||
import org.sonar.java.ast.visitors.SubscriptionVisitor; |
||||
import org.sonar.java.model.InternalSyntaxToken; |
||||
import org.sonar.java.model.expression.LiteralTreeImpl; |
||||
import org.sonar.plugins.java.api.tree.*; |
||||
|
||||
import java.util.Collections; |
||||
import java.util.List; |
||||
|
||||
/** |
||||
* TODO RSAEncryptionChecker |
||||
* |
||||
* @author RenFengJiang |
||||
* @date 2024/1/11 |
||||
*/ |
||||
@Rule(key = "RSAEncryptionChecker") |
||||
public class RSAEncryptionChecker extends SubscriptionVisitor { |
||||
|
||||
@Override |
||||
public List<Tree.Kind> nodesToVisit() { |
||||
/** |
||||
* Tree.Kind.METHOD:方法节点 |
||||
* Tree.Kind.BLOCK:方法的代码块节点 |
||||
* Tree.Kind.METHOD_INVOCATION: 方法的调用节点 |
||||
*/ |
||||
return Collections.singletonList(Tree.Kind.METHOD_INVOCATION); |
||||
} |
||||
|
||||
@Override |
||||
public void visitNode(Tree tree) { |
||||
MethodInvocationTree methodInvocationTree = (MethodInvocationTree) tree; |
||||
ExpressionTree expressionTree = methodInvocationTree.methodSelect(); |
||||
// 获取到方法调用
|
||||
if(expressionTree instanceof MemberSelectExpressionTree){ |
||||
MemberSelectExpressionTree memberSelectExpressionTree = (MemberSelectExpressionTree) expressionTree; |
||||
// 判断是否符合标准
|
||||
if("Cipher".equals(memberSelectExpressionTree.expression().toString()) && "getInstance".equals(memberSelectExpressionTree.identifier().name())){ |
||||
// 获取参数列表
|
||||
Arguments arguments = methodInvocationTree.arguments(); |
||||
if(arguments instanceof ArgumentListTreeImpl){ |
||||
// 获取到参数列表
|
||||
ArgumentListTreeImpl argumentListTree = (ArgumentListTreeImpl) arguments; |
||||
for (ExpressionTree argument : argumentListTree) { |
||||
if(argument instanceof LiteralTreeImpl){ |
||||
LiteralTreeImpl literalTree = (LiteralTreeImpl) argument; |
||||
// 获取到其中的参数
|
||||
SyntaxToken syntaxToken = literalTree.token(); |
||||
if(syntaxToken instanceof InternalSyntaxToken){ |
||||
InternalSyntaxToken internalSyntaxToken = (InternalSyntaxToken) syntaxToken; |
||||
// 对参数进行判断判断是否符合要求
|
||||
if(!(internalSyntaxToken.text().startsWith("\"RSA") && internalSyntaxToken.text().contains("OAEPWithSHA-256AndMGF1Padding"))){ |
||||
context.reportIssue(this,tree,"使用RSA最优加密填充"); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
@ -0,0 +1,9 @@ |
||||
<p>使用RSA最优加密填充</p> |
||||
<h2>使用RSA加密算法时使用最优非对称加密填充</h2> |
||||
<pre> |
||||
|
||||
</pre> |
||||
<h2>合规解决方案</h2> |
||||
<pre> |
||||
|
||||
</pre> |
@ -0,0 +1,13 @@ |
||||
{ |
||||
"title": "使用RSA最优加密填充", |
||||
"type": "CODE_SMELL", |
||||
"status": "ready", |
||||
"remediation": { |
||||
"func": "Constant\/Issue", |
||||
"constantCost": "5min" |
||||
}, |
||||
"tags": [ |
||||
"28suo" |
||||
], |
||||
"defaultSeverity": "Minor" |
||||
} |
@ -0,0 +1,30 @@ |
||||
|
||||
|
||||
public class RSAEncryptionRule { |
||||
public static void main(String[] args) throws Exception { |
||||
// 生成RSA密钥对
|
||||
KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA"); |
||||
SecureRandom secureRandom = new SecureRandom(); |
||||
keyPairGenerator.initialize(2048, secureRandom); |
||||
KeyPair keyPair = keyPairGenerator.generateKeyPair(); |
||||
PublicKey publicKey = keyPair.getPublic(); |
||||
PrivateKey privateKey = keyPair.getPrivate(); |
||||
|
||||
// 待加密的数据
|
||||
String message = "Hello, RSA!"; |
||||
|
||||
// 使用公钥进行加密
|
||||
Cipher encryptCipher = Cipher.getInstance("OAEPWith<digest>And<mgf>Padding");// Noncompliant {{使用RSA最优加密填充}}
|
||||
encryptCipher.init(Cipher.ENCRYPT_MODE, publicKey); |
||||
byte[] encryptedBytes = encryptCipher.doFinal(message.getBytes()); |
||||
|
||||
// 使用私钥进行解密
|
||||
Cipher decryptCipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding"); |
||||
decryptCipher.init(Cipher.DECRYPT_MODE, privateKey); |
||||
byte[] decryptedBytes = decryptCipher.doFinal(encryptedBytes); |
||||
|
||||
// 输出结果
|
||||
System.out.println("加密后的数据:" + new String(encryptedBytes)); |
||||
System.out.println("解密后的数据:" + new String(decryptedBytes)); |
||||
} |
||||
} |
@ -0,0 +1,33 @@ |
||||
/* |
||||
* Copyright (c) 2023 - 2024. KeyWare.Co.Ltd All rights reserved. |
||||
* 项目名称:Java 信息安全性设计准则 |
||||
* 项目描述:用于检查Java源代码的安全性设计准则的Sonarqube插件 |
||||
* 版权说明:本软件属北京关键科技股份有限公司所有,在未获得北京关键科技股份有限公司正式授权情况下,任何企业和个人,不能获取、阅读、安装、传播本软件涉及的任何受知识产权保护的内容。 |
||||
*/ |
||||
package com.keyware.sonar.java.rules.checkers; |
||||
|
||||
import com.keyware.sonar.java.utils.FilesUtils; |
||||
import org.junit.jupiter.api.Test; |
||||
import org.sonar.java.checks.verifier.CheckVerifier; |
||||
|
||||
/** |
||||
* TODO RSAEncryptionCheckerTest |
||||
* |
||||
* @author RenFengJiang |
||||
* @date 2024/1/11 |
||||
*/ |
||||
public class RSAEncryptionCheckerTest { |
||||
@Test |
||||
void detected() { |
||||
RSAEncryptionChecker rule = new RSAEncryptionChecker(); |
||||
|
||||
// Verifies that the check will raise the adequate issues with the expected message.
|
||||
// In the test file, lines which should raise an issue have been commented out
|
||||
// by using the following syntax: "// Noncompliant {{EXPECTED_MESSAGE}}"
|
||||
CheckVerifier.newVerifier() |
||||
.onFile("src/test/files/RSAEncryptionRule.java") |
||||
.withCheck(rule) |
||||
.withClassPath(FilesUtils.getClassPath("target/test-jars")) |
||||
.verifyIssues(); |
||||
} |
||||
} |
Loading…
Reference in new issue