Browse Source

修改合约打包验证功能模块

tags/1.1.0
shaozhuguang 5 years ago
parent
commit
f08f6cc9cf
11 changed files with 87 additions and 87 deletions
  1. +23
    -23
      source/contract/contract-maven-plugin/pom.xml
  2. +10
    -10
      source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java
  3. +20
    -26
      source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractVerifyMojo.java
  4. +3
    -3
      source/contract/contract-maven-plugin/src/main/resources/config.properties
  5. +1
    -1
      source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/ContractVerifyTest.java
  6. +3
    -9
      source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayInterceptServiceHandler.java
  7. +7
    -0
      source/gateway/src/main/java/com/jd/blockchain/gateway/web/TxProcessingController.java
  8. +6
    -2
      source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractCodeDeployOperationHandle.java
  9. +0
    -2
      source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java
  10. +12
    -9
      source/utils/utils-common/src/main/java/com/jd/blockchain/utils/jar/ContractJarUtils.java
  11. +2
    -2
      source/utils/utils-common/src/test/java/test/my/utils/ContractJarUtilsTest.java

+ 23
- 23
source/contract/contract-maven-plugin/pom.xml View File

@@ -103,27 +103,27 @@
<artifactId>maven-plugin-plugin</artifactId> <artifactId>maven-plugin-plugin</artifactId>
<version>3.5</version> <version>3.5</version>
</plugin> </plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<optimize>false</optimize>
<debug>true</debug>
<showDeprecation>false</showDeprecation>
<showWarnings>false</showWarnings>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<!--
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<optimize>false</optimize>
<debug>true</debug>
<showDeprecation>false</showDeprecation>
<showWarnings>false</showWarnings>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>-->
</plugins>
</build>
</project> </project>

+ 10
- 10
source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractCheckMojo.java View File

@@ -1,6 +1,5 @@
package com.jd.blockchain; package com.jd.blockchain;


import com.jd.blockchain.ledger.BlockchainKeyGenerator;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.maven.model.Model; import org.apache.maven.model.Model;
import org.apache.maven.model.Plugin; import org.apache.maven.model.Plugin;
@@ -8,6 +7,7 @@ import org.apache.maven.model.PluginExecution;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader; import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.model.io.xpp3.MavenXpp3Writer; import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
@@ -22,11 +22,12 @@ import java.util.Collections;
import java.util.List; import java.util.List;




@Mojo(name = "Contract.Check")
@Mojo(name = "contractCheck")
public class ContractCheckMojo extends AbstractMojo { public class ContractCheckMojo extends AbstractMojo {

Logger LOG = LoggerFactory.getLogger(ContractCheckMojo.class); Logger LOG = LoggerFactory.getLogger(ContractCheckMojo.class);


public static final String CONTRACT_VERIFY = "Contract.Verify";
public static final String CONTRACT_VERIFY = "contractVerify";


private static final String CONTRACT_MAVEN_PLUGIN = "contract-maven-plugin"; private static final String CONTRACT_MAVEN_PLUGIN = "contract-maven-plugin";


@@ -36,11 +37,11 @@ public class ContractCheckMojo extends AbstractMojo {


private static final String APACHE_MAVEN_PLUGINS = "org.apache.maven.plugins"; private static final String APACHE_MAVEN_PLUGINS = "org.apache.maven.plugins";


private static final String GOALS_VERIFY = "verify";
private static final String GOALS_VERIFY = "package";


private static final String GOALS_PACKAGE = "package"; private static final String GOALS_PACKAGE = "package";


private static final String OUT_POM_XML = "OutPom.xml";
private static final String OUT_POM_XML = "ContractPom.xml";


@Parameter(defaultValue = "${project}", required = true, readonly = true) @Parameter(defaultValue = "${project}", required = true, readonly = true)
private MavenProject project; private MavenProject project;
@@ -51,7 +52,6 @@ public class ContractCheckMojo extends AbstractMojo {
@Parameter @Parameter
private String finalName; private String finalName;



/** /**
* mainClass; * mainClass;
*/ */
@@ -73,11 +73,11 @@ public class ContractCheckMojo extends AbstractMojo {
* first compile the class, then parse it; * first compile the class, then parse it;
*/ */
@Override @Override
public void execute() {
public void execute() throws MojoFailureException {
compileFiles(); compileFiles();
} }


private void compileFiles(){
private void compileFiles() throws MojoFailureException {
try (FileInputStream fis = new FileInputStream(project.getFile())) { try (FileInputStream fis = new FileInputStream(project.getFile())) {


MavenXpp3Reader reader = new MavenXpp3Reader(); MavenXpp3Reader reader = new MavenXpp3Reader();
@@ -107,7 +107,7 @@ public class ContractCheckMojo extends AbstractMojo {


} catch (Exception e) { } catch (Exception e) {
LOG.error(e.getMessage()); LOG.error(e.getMessage());
throw new IllegalStateException(e);
throw new MojoFailureException(e.getMessage());
} }
} }


@@ -185,7 +185,7 @@ public class ContractCheckMojo extends AbstractMojo {
PluginExecution pluginExecution = new PluginExecution(); PluginExecution pluginExecution = new PluginExecution();
pluginExecution.setId(id); pluginExecution.setId(id);
pluginExecution.setPhase(phase); pluginExecution.setPhase(phase);
List <String> goals = new ArrayList<>();
List<String> goals = new ArrayList<>();
goals.add(goal); goals.add(goal);
pluginExecution.setGoals(goals); pluginExecution.setGoals(goals);
List<PluginExecution> pluginExecutions = new ArrayList<>(); List<PluginExecution> pluginExecutions = new ArrayList<>();


+ 20
- 26
source/contract/contract-maven-plugin/src/main/java/com/jd/blockchain/ContractVerifyMojo.java View File

@@ -3,37 +3,25 @@ package com.jd.blockchain;
import com.github.javaparser.JavaParser; import com.github.javaparser.JavaParser;
import com.github.javaparser.ast.CompilationUnit; import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.ImportDeclaration; import com.github.javaparser.ast.ImportDeclaration;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.PackageDeclaration;
import com.github.javaparser.ast.body.ClassOrInterfaceDeclaration;
import com.github.javaparser.ast.body.MethodDeclaration;
import com.github.javaparser.ast.visitor.VoidVisitorAdapter; import com.github.javaparser.ast.visitor.VoidVisitorAdapter;
import com.jd.blockchain.contract.ContractType; import com.jd.blockchain.contract.ContractType;
import com.jd.blockchain.utils.IllegalDataException;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject; import org.apache.maven.project.MavenProject;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;


import java.io.*; import java.io.*;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.jar.Attributes; import java.util.jar.Attributes;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.stream.Collectors;


import static com.jd.blockchain.ContractCheckMojo.CONTRACT_VERIFY; import static com.jd.blockchain.ContractCheckMojo.CONTRACT_VERIFY;
import static com.jd.blockchain.utils.decompiler.utils.DecompilerUtils.decompileJarFile; import static com.jd.blockchain.utils.decompiler.utils.DecompilerUtils.decompileJarFile;
@@ -78,12 +66,15 @@ public class ContractVerifyMojo extends AbstractMojo {
private static final String BLACK_NAME_LIST = "black.name.list"; private static final String BLACK_NAME_LIST = "black.name.list";


@Override @Override
public void execute() throws MojoFailureException {
public void execute() throws MojoExecutionException {


try { try {


File jarFile = copyAndManage(); File jarFile = copyAndManage();


// 首先校验MainClass
verifyMainClass(jarFile);

Properties config = loadConfig(); Properties config = loadConfig();


List<ContractPackage> blackNameList = blackNameList(config); List<ContractPackage> blackNameList = blackNameList(config);
@@ -193,23 +184,25 @@ public class ContractVerifyMojo extends AbstractMojo {
if (!isOK) { if (!isOK) {
throw new IllegalStateException("There are many Illegal information, please check !!!"); throw new IllegalStateException("There are many Illegal information, please check !!!");
} }

// 加载main-class,开始校验类型
URL jarURL = jarFile.toURI().toURL();
ClassLoader classLoader = new URLClassLoader(new URL[]{jarURL}, this.getClass().getClassLoader());
Attributes m = new JarFile(jarFile).getManifest().getMainAttributes();
String contractMainClass = m.getValue(Attributes.Name.MAIN_CLASS);
Class mainClass = classLoader.loadClass(contractMainClass);
ContractType.resolve(mainClass);
} else { } else {
throw new IllegalStateException("There is none class !!!"); throw new IllegalStateException("There is none class !!!");
} }
} catch (Exception e) { } catch (Exception e) {
LOG.error(e.getMessage()); LOG.error(e.getMessage());
throw new MojoFailureException(e.getMessage());
throw new MojoExecutionException(e.getMessage());
} }
} }


private void verifyMainClass(File jarFile) throws Exception {
// 加载main-class,开始校验类型
URL jarURL = jarFile.toURI().toURL();
ClassLoader classLoader = new URLClassLoader(new URL[]{jarURL}, this.getClass().getClassLoader());
Attributes m = new JarFile(jarFile).getManifest().getMainAttributes();
String contractMainClass = m.getValue(Attributes.Name.MAIN_CLASS);
Class mainClass = classLoader.loadClass(contractMainClass);
ContractType.resolve(mainClass);
}

private List<ContractPackage> blackNameList(Properties config) { private List<ContractPackage> blackNameList(Properties config) {
return blackList(config, BLACK_NAME_LIST); return blackList(config, BLACK_NAME_LIST);
} }
@@ -320,14 +313,14 @@ public class ContractVerifyMojo extends AbstractMojo {
// 首先进行Copy处理 // 首先进行Copy处理
copy(srcJar, dstJar); copy(srcJar, dstJar);


byte[] txtBytes = jdChainTxt(FileUtils.readFileToByteArray(dstJar)).getBytes(StandardCharsets.UTF_8);
byte[] txtBytes = contractMF(FileUtils.readFileToByteArray(dstJar)).getBytes(StandardCharsets.UTF_8);


String finalJarPath = project.getBuild().getDirectory() + String finalJarPath = project.getBuild().getDirectory() +
File.separator + finalName + "-jdchain.jar"; File.separator + finalName + "-jdchain.jar";


File finalJar = new File(finalJarPath); File finalJar = new File(finalJarPath);


copy(dstJar, finalJar, jdChainMetaTxtJarEntry(), txtBytes, null);
copy(dstJar, finalJar, contractMFJarEntry(), txtBytes, null);


// 删除临时文件 // 删除临时文件
FileUtils.forceDelete(dstJar); FileUtils.forceDelete(dstJar);
@@ -423,8 +416,9 @@ public class ContractVerifyMojo extends AbstractMojo {
if (totalPackage.endsWith("*")) { if (totalPackage.endsWith("*")) {
this.packageName = totalPackage.substring(0, totalPackage.length() - 2).trim(); this.packageName = totalPackage.substring(0, totalPackage.length() - 2).trim();
this.isTotal = true; this.isTotal = true;
} else {
this.packageName = totalPackage;
} }
this.packageName = totalPackage;
} }


public String getPackageName() { public String getPackageName() {


+ 3
- 3
source/contract/contract-maven-plugin/src/main/resources/config.properties View File

@@ -1,8 +1,8 @@
#black.name.list:打包为合约Jar后,每个Class文件不允许使用的名称,默认不允许使用com.jd.blockchain.*
black.name.list=com.jd.blockchain.*
#black.name.list:打包为合约Jar后,每个Class文件不允许使用或包含的名称,默认不允许使用com.jd.blockchain.*及一些内部已经引用的包
black.name.list=com.jd.blockchain.*, com.alibaba.fastjson.*, org.apache.commons.io.*, org.apache.commons.codec.*, io.netty.*


#black.package.list:打包为合约中的每个Class都不允许使用的包列表,某个包下面的所有包通过.*表示 #black.package.list:打包为合约中的每个Class都不允许使用的包列表,某个包下面的所有包通过.*表示
black.package.list=java.io.*, java.net.*, org.apache.commons.io.*
black.package.list=java.io.*, java.nio.*, java.net.*, org.apache.commons.io.*


#black.class.list:打包为合约中的每个Class都不允许使用的类列表 #black.class.list:打包为合约中的每个Class都不允许使用的类列表
black.class.list=java.util.Random, com.jd.blockchain.ledger.BlockchainKeyGenerator black.class.list=java.util.Random, com.jd.blockchain.ledger.BlockchainKeyGenerator

+ 1
- 1
source/contract/contract-maven-plugin/src/test/java/com/jd/blockchain/ledger/ContractVerifyTest.java View File

@@ -18,7 +18,7 @@ public class ContractVerifyTest {
@Before @Before
public void testInit() { public void testInit() {
project = mavenProjectInit(); project = mavenProjectInit();
finalName = "complex.jar";
finalName = "complex";
} }


@Test @Test


+ 3
- 9
source/gateway/src/main/java/com/jd/blockchain/gateway/service/GatewayInterceptServiceHandler.java View File

@@ -5,6 +5,7 @@ import com.jd.blockchain.ledger.ContractCodeDeployOperation;
import com.jd.blockchain.ledger.Operation; import com.jd.blockchain.ledger.Operation;
import com.jd.blockchain.ledger.TransactionRequest; import com.jd.blockchain.ledger.TransactionRequest;
import com.jd.blockchain.utils.IllegalDataException; import com.jd.blockchain.utils.IllegalDataException;
import com.jd.blockchain.utils.jar.ContractJarUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;


@@ -29,14 +30,7 @@ public class GatewayInterceptServiceHandler implements GatewayInterceptService {
} }


private void contractCheck(final ContractCodeDeployOperation contractOP) { private void contractCheck(final ContractCodeDeployOperation contractOP) {
//
byte[] chainCode = contractOP.getChainCode();
if (chainCode == null || chainCode.length == 0) {
throw new IllegalDataException("Contract's content is empty !!!");
}




// 校验chainCode
ContractJarUtils.verify(contractOP.getChainCode());
} }
} }

+ 7
- 0
source/gateway/src/main/java/com/jd/blockchain/gateway/web/TxProcessingController.java View File

@@ -1,5 +1,6 @@
package com.jd.blockchain.gateway.web; package com.jd.blockchain.gateway.web;


import com.jd.blockchain.gateway.service.GatewayInterceptService;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
@@ -30,9 +31,15 @@ public class TxProcessingController implements TransactionService {
@Autowired @Autowired
private PeerService peerService; private PeerService peerService;


@Autowired
private GatewayInterceptService interceptService;

@RequestMapping(path = "rpc/tx", method = RequestMethod.POST, consumes = BinaryMessageConverter.CONTENT_TYPE_VALUE, produces = BinaryMessageConverter.CONTENT_TYPE_VALUE) @RequestMapping(path = "rpc/tx", method = RequestMethod.POST, consumes = BinaryMessageConverter.CONTENT_TYPE_VALUE, produces = BinaryMessageConverter.CONTENT_TYPE_VALUE)
@Override @Override
public @ResponseBody TransactionResponse process(@RequestBody TransactionRequest txRequest) { public @ResponseBody TransactionResponse process(@RequestBody TransactionRequest txRequest) {
// 拦截请求进行校验
interceptService.intercept(txRequest);

// 检查交易请求的信息是否完整; // 检查交易请求的信息是否完整;
HashDigest ledgerHash = txRequest.getTransactionContent().getLedgerHash(); HashDigest ledgerHash = txRequest.getTransactionContent().getLedgerHash();
if (ledgerHash == null) { if (ledgerHash == null) {


+ 6
- 2
source/ledger/ledger-core/src/main/java/com/jd/blockchain/ledger/core/impl/handles/ContractCodeDeployOperationHandle.java View File

@@ -1,5 +1,6 @@
package com.jd.blockchain.ledger.core.impl.handles; package com.jd.blockchain.ledger.core.impl.handles;


import com.jd.blockchain.utils.jar.ContractJarUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;


import com.jd.blockchain.ledger.BytesValue; import com.jd.blockchain.ledger.BytesValue;
@@ -22,8 +23,12 @@ public class ContractCodeDeployOperationHandle implements OperationHandle {
// TODO: 请求者应该提供合约账户的公钥签名,已确定注册的地址的唯一性; // TODO: 请求者应该提供合约账户的公钥签名,已确定注册的地址的唯一性;


byte[] chainCode = contractOP.getChainCode();
// 校验合约代码,不通过会抛出异常
ContractJarUtils.verify(chainCode);

dataset.getContractAccountSet().deploy(contractOP.getContractID().getAddress(), dataset.getContractAccountSet().deploy(contractOP.getContractID().getAddress(),
contractOP.getContractID().getPubKey(), contractOP.getAddressSignature(), contractOP.getChainCode());
contractOP.getContractID().getPubKey(), contractOP.getAddressSignature(), chainCode);


return null; return null;
} }
@@ -37,5 +42,4 @@ public class ContractCodeDeployOperationHandle implements OperationHandle {
public boolean support(Class<?> operationType) { public boolean support(Class<?> operationType) {
return ContractCodeDeployOperation.class.isAssignableFrom(operationType); return ContractCodeDeployOperation.class.isAssignableFrom(operationType);
} }

} }

+ 0
- 2
source/ledger/ledger-model/src/main/java/com/jd/blockchain/transaction/BlockchainOperationFactory.java View File

@@ -260,8 +260,6 @@ public class BlockchainOperationFactory implements ClientOperator, LedgerInitOpe
private class ContractCodeDeployOperationBuilderFilter implements ContractCodeDeployOperationBuilder { private class ContractCodeDeployOperationBuilderFilter implements ContractCodeDeployOperationBuilder {
@Override @Override
public ContractCodeDeployOperation deploy(BlockchainIdentity id, byte[] chainCode) { public ContractCodeDeployOperation deploy(BlockchainIdentity id, byte[] chainCode) {
// 校验chainCode
ContractJarUtils.verify(chainCode);
// 校验成功后发布 // 校验成功后发布
ContractCodeDeployOperation op = CONTRACT_CODE_DEPLOY_OP_BUILDER.deploy(id, chainCode); ContractCodeDeployOperation op = CONTRACT_CODE_DEPLOY_OP_BUILDER.deploy(id, chainCode);
operationList.add(op); operationList.add(op);


+ 12
- 9
source/utils/utils-common/src/main/java/com/jd/blockchain/utils/jar/ContractJarUtils.java View File

@@ -15,13 +15,16 @@ import java.util.jar.JarOutputStream;


public class ContractJarUtils { public class ContractJarUtils {


private static final String JDCHAIN_META = "META-INF/CONTRACT.MF";
private static final String CONTRACT_MF = "META-INF/CONTRACT.MF";


private static final int JDCHAIN_HASH_LENGTH = 69; private static final int JDCHAIN_HASH_LENGTH = 69;


private static final Random FILE_RANDOM = new Random(); private static final Random FILE_RANDOM = new Random();


public static void verify(byte[] chainCode) { public static void verify(byte[] chainCode) {
if (chainCode == null || chainCode.length == 0) {
throw new IllegalStateException("ChainCode is empty !!!");
}
// 首先生成合约文件 // 首先生成合约文件
File jarFile = newJarFile(); File jarFile = newJarFile();
try { try {
@@ -42,14 +45,14 @@ public class ContractJarUtils {


private static void verify(File jarFile) throws Exception { private static void verify(File jarFile) throws Exception {
// 首先判断jarFile中是否含有META-INF/JDCHAIN.TXT,并将其读出 // 首先判断jarFile中是否含有META-INF/JDCHAIN.TXT,并将其读出
URL jarUrl = new URL("jar:file:" + jarFile.getPath() + "!/" + JDCHAIN_META);
URL jarUrl = new URL("jar:file:" + jarFile.getPath() + "!/" + CONTRACT_MF);
InputStream inputStream = jarUrl.openStream(); InputStream inputStream = jarUrl.openStream();
if (inputStream == null) { if (inputStream == null) {
throw new IllegalStateException(JDCHAIN_META + " IS NULL !!!");
throw new IllegalStateException(CONTRACT_MF + " IS NULL !!!");
} }
byte[] bytes = IOUtils.toByteArray(inputStream); byte[] bytes = IOUtils.toByteArray(inputStream);
if (bytes == null || bytes.length != JDCHAIN_HASH_LENGTH) { if (bytes == null || bytes.length != JDCHAIN_HASH_LENGTH) {
throw new IllegalStateException(JDCHAIN_META + " IS Illegal !!!");
throw new IllegalStateException(CONTRACT_MF + " IS Illegal !!!");
} }
// 获取对应的Hash内容 // 获取对应的Hash内容
String txt = new String(bytes, StandardCharsets.UTF_8); String txt = new String(bytes, StandardCharsets.UTF_8);
@@ -58,10 +61,10 @@ public class ContractJarUtils {
File tempJar = newJarFile(); File tempJar = newJarFile();


// 复制除JDCHAIN.TXT之外的部分 // 复制除JDCHAIN.TXT之外的部分
copy(jarFile, tempJar, null, null, JDCHAIN_META);
copy(jarFile, tempJar, null, null, CONTRACT_MF);


// 生成新Jar包对应的Hash内容 // 生成新Jar包对应的Hash内容
String verifyTxt = jdChainTxt(FileUtils.readFileToByteArray(tempJar));
String verifyTxt = contractMF(FileUtils.readFileToByteArray(tempJar));


// 删除临时文件 // 删除临时文件
FileUtils.forceDelete(tempJar); FileUtils.forceDelete(tempJar);
@@ -103,13 +106,13 @@ public class ContractJarUtils {
jarFile.close(); jarFile.close();
} }


public static String jdChainTxt(byte[] content) {
public static String contractMF(byte[] content) {
// hash=Hex(hash(content)) // hash=Hex(hash(content))
return "hash:" + DigestUtils.sha256Hex(content); return "hash:" + DigestUtils.sha256Hex(content);
} }


public static JarEntry jdChainMetaTxtJarEntry() {
return new JarEntry(JDCHAIN_META);
public static JarEntry contractMFJarEntry() {
return new JarEntry(CONTRACT_MF);
} }


private static byte[] readStream(InputStream inputStream) { private static byte[] readStream(InputStream inputStream) {


+ 2
- 2
source/utils/utils-common/src/test/java/test/my/utils/ContractJarUtilsTest.java View File

@@ -34,14 +34,14 @@ public class ContractJarUtilsTest {
// 首先进行Copy处理 // 首先进行Copy处理
copy(srcJar, dstJar); copy(srcJar, dstJar);


byte[] txtBytes = jdChainTxt(FileUtils.readFileToByteArray(dstJar)).getBytes(StandardCharsets.UTF_8);
byte[] txtBytes = contractMF(FileUtils.readFileToByteArray(dstJar)).getBytes(StandardCharsets.UTF_8);


String finalJarPath = classPath + String finalJarPath = classPath +
File.separator + jarName + "-jdchain.jar"; File.separator + jarName + "-jdchain.jar";


File finalJar = new File(finalJarPath); File finalJar = new File(finalJarPath);


copy(dstJar, finalJar, jdChainMetaTxtJarEntry(), txtBytes, null);
copy(dstJar, finalJar, contractMFJarEntry(), txtBytes, null);


// 删除临时文件 // 删除临时文件
FileUtils.forceDelete(dstJar); FileUtils.forceDelete(dstJar);


Loading…
Cancel
Save