Skip to content

Commit

Permalink
修改容器命名和异常抛出
Browse files Browse the repository at this point in the history
资源定位器无法获取根目录下文件的问题
  • Loading branch information
Trisia committed Apr 22, 2020
1 parent 5ca3de3 commit 0fac823
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 74 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ mvn install
期望新功能

- 电子签名/签章以及验证。
- 行内换行。
- 段落的行内布局控制(text-align)能让固定布局样式文字居中。
- 页面模板、页面模板导入使用。
- 水印。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,11 @@ public ResourceLocator restWd() {

/**
* 切换到制定的虚拟容器目录下
*
* @param vc 虚拟容器
* @return this
*/
public ResourceLocator cd(VirtualContainer vc){
public ResourceLocator cd(VirtualContainer vc) {
if (vc == null) {
throw new IllegalArgumentException("改变目录的容器对象(vc)为空");
}
Expand Down Expand Up @@ -319,7 +320,7 @@ public <R> R get(String loc, Function<Element, R> mapper) throws FileNotFoundExc
int indexOf = loc.lastIndexOf('/');
if (indexOf != -1) {
// 切换工作目录
this.cd(wd, loc.substring(0, indexOf));
this.cd(wd, loc.substring(0, indexOf + 1));
fileName = loc.substring(indexOf + 1);
} else {
fileName = loc;
Expand Down Expand Up @@ -349,7 +350,7 @@ public Path getFile(ST_Loc stLoc) throws FileNotFoundException {
int indexOf = loc.lastIndexOf('/');
if (indexOf != -1) {
// 切换工作目录
this.cd(wd, loc.substring(0, indexOf));
this.cd(wd, loc.substring(0, indexOf + 1));
fileName = loc.substring(indexOf + 1);
} else {
fileName = loc;
Expand Down
32 changes: 19 additions & 13 deletions ofdrw-sign/src/main/java/org/ofdrw/sign/verify/OFDValidator.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,15 @@
import org.ofdrw.sign.verify.exceptions.DocNotSignException;
import org.ofdrw.sign.verify.exceptions.FileIntegrityException;
import org.ofdrw.sign.verify.exceptions.OFDVerifyException;
import org.ofdrw.sign.verify.exceptions.SESInvalidException;
import org.ofdrw.sign.verify.exceptions.InvalidSignedValueException;

import java.io.Closeable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Provider;
import java.security.*;
import java.util.Arrays;
import java.util.List;

Expand Down Expand Up @@ -65,7 +62,7 @@ public class OFDValidator implements Closeable {
/**
* 电子印章
*/
private SESValidateContainer validator;
private SignedDataValidateContainer validator;

/**
* 创建一个OFD验证引擎
Expand All @@ -88,7 +85,7 @@ public OFDValidator(OFDReader reader) {
* @throws IOException 文件读写过程中IO异常
* @throws NoSuchAlgorithmException 未知的杂凑算法
*/
public void exeValidate() throws OFDVerifyException, IOException, NoSuchAlgorithmException {
public void exeValidate() throws OFDVerifyException, IOException, GeneralSecurityException {
rl.save();
try {
rl.cd("/");
Expand Down Expand Up @@ -125,8 +122,10 @@ public void exeValidate() throws OFDVerifyException, IOException, NoSuchAlgorith
// 2. 检查印章匹配
checkSealMatch(sealFilePath, signedValueFilePath);
}
// 签名算法名称
String alg = sig.getSignedInfo().getSignatureMethod();
// 3. 验证电子签名或签章数据
checkSES(type, signatureFilePath, signedValueFilePath);
checkSES(type, alg, signatureFilePath, signedValueFilePath);
} finally {
rl.restore();
}
Expand All @@ -142,30 +141,37 @@ public void exeValidate() throws OFDVerifyException, IOException, NoSuchAlgorith
* 设置用于电子签章数据验证的容器
*
* @param validator 验证容器
* @return this
*/
public void setValidator(SESValidateContainer validator) {
public OFDValidator setValidator(SignedDataValidateContainer validator) {
if (validator == null) {
throw new IllegalArgumentException("电子签章数据验证容器(validator)为空");
}
this.validator = validator;
return this;
}

/**
* 检查电子签章数据
*
* @param type 验证类型 数字签名/电子签章
* @param alg 算法名称
* @param signatureFilePath 签名文件(Signature.xml)路径
* @param signedValuePath 签名值文件(SignedValue.dat)路径
* @throws SESInvalidException 电子签章数据失效
* @throws IOException IO异常
* @throws InvalidSignedValueException 电子签章数据失效
* @throws IOException IO异常
*/
public void checkSES(SigType type, Path signatureFilePath, Path signedValuePath) throws IOException, SESInvalidException {
public void checkSES(SigType type, String alg, Path signatureFilePath, Path signedValuePath) throws IOException, GeneralSecurityException {
if (validator == null) {
throw new IllegalArgumentException("电子签章数据验证容器(validator)为空,Call #setValidator");
}
if (type == null) {
type = SigType.Seal;
}
validator.validate(type, Files.readAllBytes(signatureFilePath), Files.readAllBytes(signedValuePath));
validator.validate(type,
alg,
Files.readAllBytes(signatureFilePath),
Files.readAllBytes(signedValuePath));
}

/**
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package org.ofdrw.sign.verify;

import org.ofdrw.core.signatures.SigType;
import org.ofdrw.sign.verify.exceptions.InvalidSignedValueException;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;

/**
* 签名数据验证
*
* @author 权观宇
* @since 2020-04-22 02:25:08
*/
public interface SignedDataValidateContainer {

/**
* 签名数据验证
* <p>
* 如果验证不通过请抛出异常
*
* @param type 电子签名类型(Sign/Seal)
* @param signAlgName 签名算法名称或OID
* @param tbsContent 待签章内容
* @param signedValue 电子签章数据或签名值
* @throws InvalidSignedValueException 电子签章数据失效
* @throws IOException IO异常
* @throws GeneralSecurityException 运算过程中异常
*/
void validate(SigType type, String signAlgName, byte[] tbsContent, byte[] signedValue) throws InvalidSignedValueException, IOException, GeneralSecurityException;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package org.ofdrw.sign.verify.container;

import org.bouncycastle.jcajce.provider.asymmetric.x509.CertificateFactory;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.ofdrw.core.signatures.SigType;
import org.ofdrw.sign.verify.SignedDataValidateContainer;
import org.ofdrw.sign.verify.exceptions.InvalidSignedValueException;

import java.io.IOException;
import java.security.GeneralSecurityException;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;

/**
* 数字签名验证容器
*
* @author 权观宇
* @since 2020-04-22 03:22:22
*/
public class DigitalSignContainer implements SignedDataValidateContainer {
/**
* 验证使用的公钥
*/
public PublicKey pk;

public DigitalSignContainer(PublicKey pk) {
if (pk == null) {
throw new IllegalArgumentException("验证使用的公钥参数(pk)不能为空");
}
this.pk = pk;
}

public DigitalSignContainer(Certificate certificate) {
this(certificate.getPublicKey());
}

@Override
public void validate(SigType type, String alg, byte[] tbsContent, byte[] signedValue)
throws InvalidSignedValueException, GeneralSecurityException {
if (type != SigType.Sign) {
throw new IllegalArgumentException("签名类型(type)必须是 Sign,不支持电子印章验证");
}
Signature sg = Signature.getInstance(alg, new BouncyCastleProvider());
sg.initVerify(pk);
if (!sg.verify(signedValue)) {
throw new InvalidSignedValueException("签名值不一致");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package org.ofdrw.sign.verify.exceptions;

/**
* 电子签章数据失效异常
* 电子签名数据失效异常
*
* @author 权观宇
* @since 2020-04-22 02:17:28
*/
public class SESInvalidException extends OFDVerifyException {
public class InvalidSignedValueException extends OFDVerifyException {
/**
* 失效原因
*/
Expand All @@ -17,12 +17,12 @@ public class SESInvalidException extends OFDVerifyException {
*/
private Integer code;

public SESInvalidException(String reason) {
public InvalidSignedValueException(String reason) {
super("电子签章数据失效:" + reason);
this.reason = reason;
}

public SESInvalidException(String reason, Throwable cause) {
public InvalidSignedValueException(String reason, Throwable cause) {
super("电子签章数据失效:" + reason, cause);
this.reason = reason;
}
Expand Down
26 changes: 0 additions & 26 deletions ofdrw-sign/src/test/java/org/ofdrw/sign/OFDSignerTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,31 +34,5 @@
class OFDSignerTest {


/**
* OFD电子签名演示
*/
@Test
void testDigestSign() throws GeneralSecurityException, IOException {
Path userP12Path = Paths.get("src/test/resources", "USER.p12");
PrivateKey prvKey = PKCS12Tools.ReadPrvKey(userP12Path, "private", "777777");

Path src = Paths.get("src/test/resources", "helloworld.ofd");
Path out = Paths.get("target/DigestSign.ofd");
// 1. 构造签名引擎
try (OFDReader reader = new OFDReader(src);
OFDSigner signer = new OFDSigner(reader, out)) {
GMDigestSignatureContainer signContainer = new GMDigestSignatureContainer(prvKey);
// 2. 设置签名模式
// signer.setSignMode(SignMode.WholeProtected);
signer.setSignMode(SignMode.ContinueSign);
// 3. 设置签名使用的扩展签名容器
signer.setSignContainer(signContainer);
// 4. 执行签名
signer.exeSign();
// 5. 关闭签名引擎,生成文档。
}
System.out.println(">> 生成文件位置: " + out.toAbsolutePath().toAbsolutePath());
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package org.ofdrw.sign.signContainer;

import org.junit.jupiter.api.Test;
import org.ofdrw.gm.cert.PKCS12Tools;
import org.ofdrw.reader.OFDReader;
import org.ofdrw.sign.OFDSigner;
import org.ofdrw.sign.SignMode;

import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.security.PrivateKey;

import static org.junit.jupiter.api.Assertions.*;

/**
* 数据签名演示
*
* @author 权观宇
* @since 2020-04-22 03:16:01
*/
class GMDigestSignatureContainerTest {

/**
* OFD电子签名演示
*/
@Test
void testDigestSign() throws GeneralSecurityException, IOException {
Path userP12Path = Paths.get("src/test/resources", "USER.p12");
PrivateKey prvKey = PKCS12Tools.ReadPrvKey(userP12Path, "private", "777777");

Path src = Paths.get("src/test/resources", "helloworld.ofd");
Path out = Paths.get("target/DigestSign.ofd");
// 1. 构造签名引擎
try (OFDReader reader = new OFDReader(src);
OFDSigner signer = new OFDSigner(reader, out)) {
GMDigestSignatureContainer signContainer = new GMDigestSignatureContainer(prvKey);
// 2. 设置签名模式
// signer.setSignMode(SignMode.WholeProtected);
signer.setSignMode(SignMode.ContinueSign);
// 3. 设置签名使用的扩展签名容器
signer.setSignContainer(signContainer);
// 4. 执行签名
signer.exeSign();
// 5. 关闭签名引擎,生成文档。
}
System.out.println(">> 生成文件位置: " + out.toAbsolutePath().toAbsolutePath());
}

}
Loading

0 comments on commit 0fac823

Please sign in to comment.