问题描述:项目需要使用secp256k1类型的椭圆曲线进行加解密,客户端是用java实现的,而后台是用golang。问题在于java有secp256k1的标准库,可以生成密钥和加密,通过x509序列化之后传给golang后台,但是golang没有该标准库,无法进行验证。
解决方案(两种):
- 对照java的标准库用golang自行实现可用的椭圆曲线(待定)
- java实现验证,编成jar包,利用golang中的os/exec包调用jar,得到结果
准备: java和golang的运行环境
java代码(验证):
import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;
import com.sun.org.apache.xerces.internal.impl.dv.util.HexBin;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;
/**
* Created by bqh on 2017/4/8.
* <p>
* E-mail:M201672845@hust.edu.cn
*/
public class Verify {
public static void main(String[] args) throws NoSuchAlgorithmException, NoSuchProviderException, InvalidKeySpecException,
InvalidAlgorithmParameterException,InvalidKeyException,SignatureException {
if (args.length != 3) {
System.out.println("args length invalid");
}
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
X509EncodedKeySpec x509EncodedKeySpec = new X509EncodedKeySpec(Base64.decode(args[0]));
KeyFactory fact = KeyFactory.getInstance("ECDSA", "BC");
PublicKey publicKey = fact.generatePublic(x509EncodedKeySpec);
Signature signature = Signature.getInstance("SHA1withECDSA");
signature.initVerify(publicKey);
signature.update(args[1].getBytes());
boolean flag = signature.verify(HexBin.decode(args[2]));
System.out.println(flag);
}
}
用idea生成一个jar文件Verify.jar,能在命令行中成功运行
java -jar Verify.jar 参数1 参数2 参数3
即可认定jar可用(我遇到报错Invalid signature file digest for Manifest main attributes,这是由于jar签名不合法,用winrar打开该jar,删除.SF文件即可)
golang调用代码:
package main
import (
"fmt"
"os/exec"
)
const (
sigScript string = "3046022100E4C617A5626E408938EEAC33D7BC0ACD645D8FF0B9A29FE55EC3F9BAB01A07C9022100D0F9E8A545E997F3E431C5E3DADA0EC5F53ACE6A7E9598FD6F3B85BE055D3E10"
unsignedTx string = "bqh"
pubScr string = "MFYwEAYHKoZIzj0CAQYFK4EEAAoDQgAEnpwnu94soZ/z9QdfTEwJAY+Qhz34pLsNFZA/OgmhekTIBBdJyxpHs4GaId3wWrq11OyqmJlu2qCLDtZcGFBjdA=="
priScr string = "MIGNAgEAMBAGByqGSM49AgEGBSuBBAAKBHYwdAIBAQQg49U3dRtNk+WZ6E1BJKIM8oHP2zm766HFTF9jjP1RM9qgBwYFK4EEAAqhRANCAASwYY8XyIPfiNnfkC25axj/Lw6Eq64hVaz34PKquSwiujCk3tB21VivJwrUJkXhkCmAxYsYhF6izcNLpOAvDrPO"
)
func main() {
cmd := exec.Command("java", "-jar", "Verify.jar", pubScr, unsignedTx, sigScript)
out, err := cmd.Output()
if err != nil {
fmt.Println(err)
}
fmt.Print(string(out))
}
成功返回true!
这种方法看起来不太安全,下一步计划用golang实现secp256k1类型的椭圆曲线。
参考资料:
- 建议尝试的GoJVM(未使用) https://github.com/abneptis/GoJVM
- 依赖包:bcpkix-jdk15on-156.jar、bcprov-ext-jdk15on-156.jar、core-1.54.0.0.jar