使用 Go 生成 SHA256withDSA 签名,然后使用 Java 验证它
generate a SHA256withDSA signature using Go and then verify it using Java
- 使用 sha256 原始数据然后进行 DSA 签名
- 十六进制打印符号结果
- 使用Java SHA256withDSA 验证第一步结果return false
- 我知道 sha256 然后 DSA 是 SHA256 和 DSA 的区别
- 我如何在 Go 中生成一个符号,可以在 Java 中使用 sha256withdsa 进行验证?
- Go 有任何其他第三方库支持吗?
开始
package main
import (
"crypto/dsa"
"crypto/rand"
"crypto/sha256"
"encoding/asn1"
"encoding/hex"
"fmt"
"golang.org/x/crypto/ssh"
"math/big"
)
func main() {
pemData := []byte("-----BEGIN DSA PRIVATE KEY-----\n" +
"MIIBvAIBAAKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR\n" +
"+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb\n" +
"+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdg\n" +
"UI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlX\n" +
"TAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCj\n" +
"rh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQB\n" +
"TDv+z0kqAoGBAIb9o0KPsjAdzjK571e1Mx7ZhEyJGrcxHiN2sW8IztEbqrKKiMxp\n" +
"NlTwm234uBdtzVHE3uDWZpfHPMIRmwBjCYDFRowWWVRdhdFXZlpCyp1gMWqJ11dh\n" +
"3FI3+O43DevRSyyuLRVCNQ1J3iVgwY5ndRpZU7n6y8DPH4/4EBT7KvnVAhR4Vwun\n" +
"Fhu/+4AGaVeMEa814I3dqg==\n" +
"-----END DSA PRIVATE KEY-----")
p, _ := ssh.ParseRawPrivateKey(pemData)
pp := p.(*dsa.PrivateKey)
hashed := []byte{1}
sha256 := sha256.New()
sha256.Write(hashed)
hashed = sha256.Sum(nil)
r, s, _ := dsa.Sign(rand.Reader, pp, hashed)
type dsaSignature struct {
R, S *big.Int
}
var ss dsaSignature
ss.S = s
ss.R = r
signatureBytes, _ := asn1.Marshal(ss)
fmt.Println(hex.EncodeToString(signatureBytes))
}
Java
@Test
public void ttt() throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
String pubKey = "-----BEGIN PUBLIC KEY-----\n" +
"MIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E\n" +
"AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f\n" +
"6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv\n" +
"8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtc\n" +
"NrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwky\n" +
"jMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/h\n" +
"WuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUAAoGBAIb9o0KPsjAdzjK571e1Mx7ZhEyJ\n" +
"GrcxHiN2sW8IztEbqrKKiMxpNlTwm234uBdtzVHE3uDWZpfHPMIRmwBjCYDFRowW\n" +
"WVRdhdFXZlpCyp1gMWqJ11dh3FI3+O43DevRSyyuLRVCNQ1J3iVgwY5ndRpZU7n6\n" +
"y8DPH4/4EBT7KvnV\n" +
"-----END PUBLIC KEY-----";
String publicKeyPEM = pubKey
.replace("-----BEGIN PUBLIC KEY-----\n", "")
.replaceAll(System.lineSeparator(), "")
.replace("-----END PUBLIC KEY-----", "");
byte[] publicEncoded = Base64.decodeBase64(publicKeyPEM);
KeyFactory keyFactory1 = KeyFactory.getInstance("DSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicEncoded);
DSAPublicKey pubKeyy = (DSAPublicKey) keyFactory1.generatePublic(publicKeySpec);
Signature sig1 = Signature.getInstance("SHA256withDSA");
sig1.initVerify(pubKeyy);
byte[] orignData = new byte[]{1};
sig1.update(orignData);
boolean flag = sig1.verify(HexUtil.decodeHex("first step result"));
System.out.println(flag);
}
我在 java
中找到
package sun.security.provider;
private BigInteger generateS(BigInteger var1, BigInteger var2, BigInteger var3, BigInteger var4) throws SignatureException {
byte[] var5;
try {
var5 = this.md.digest();
} catch (RuntimeException var9) {
throw new SignatureException(var9.getMessage());
}
// this line split the hash256 redsult
int var6 = var2.bitLength() / 8;
if (var6 < var5.length) {
var5 = Arrays.copyOfRange(var5, 0, var6);
}
BigInteger var7 = new BigInteger(1, var5);
BigInteger var8 = var4.modInverse(var2);
return var1.multiply(var3).add(var7).multiply(var8).mod(var2);
}
你可以在golang中使用
hashed := []byte{1}
sha256 := sha2562.New()
sha256.Write(hashed)
hashed = sha256.Sum(nil)
// you must split it
hashed = hashed[0:20]
原因是 sha256 结果在 java 中拆分,但 glang 没有拆分
遵循 FIPS186-4 第 4.6 和 4.7 节 golang
hashed := []byte{1}
pemData, _ := ioutil.ReadFile("config/secure/private.key")
p, err := ssh.ParseRawPrivateKey(pemData)
pp, ok := p.(*dsa.PrivateKey)
h := sha256.New()
h.Write(hashed)
hashed := h.Sum(nil)
if pp.Q.BitLen()/8 < len(hashed) {
hashed = hashed[0 : pp.Q.BitLen()/8]
}
r, s, _ := dsa.Sign(rand.Reader, pp, hashed)
var ss dsaSignature
ss.S = s
ss.R = r
hashed, _ = asn1.Marshal(ss)
- 使用 sha256 原始数据然后进行 DSA 签名
- 十六进制打印符号结果
- 使用Java SHA256withDSA 验证第一步结果return false
- 我知道 sha256 然后 DSA 是 SHA256 和 DSA 的区别
- 我如何在 Go 中生成一个符号,可以在 Java 中使用 sha256withdsa 进行验证?
- Go 有任何其他第三方库支持吗?
开始
package main
import (
"crypto/dsa"
"crypto/rand"
"crypto/sha256"
"encoding/asn1"
"encoding/hex"
"fmt"
"golang.org/x/crypto/ssh"
"math/big"
)
func main() {
pemData := []byte("-----BEGIN DSA PRIVATE KEY-----\n" +
"MIIBvAIBAAKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEmaUVdQCJR\n" +
"+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb\n" +
"+DtX58aophUPBPuD9tPFHsMCNVQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdg\n" +
"UI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jrqgvlX\n" +
"TAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCj\n" +
"rh4rs6Z1kW6jfwv6ITVi8ftiegEkO8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQB\n" +
"TDv+z0kqAoGBAIb9o0KPsjAdzjK571e1Mx7ZhEyJGrcxHiN2sW8IztEbqrKKiMxp\n" +
"NlTwm234uBdtzVHE3uDWZpfHPMIRmwBjCYDFRowWWVRdhdFXZlpCyp1gMWqJ11dh\n" +
"3FI3+O43DevRSyyuLRVCNQ1J3iVgwY5ndRpZU7n6y8DPH4/4EBT7KvnVAhR4Vwun\n" +
"Fhu/+4AGaVeMEa814I3dqg==\n" +
"-----END DSA PRIVATE KEY-----")
p, _ := ssh.ParseRawPrivateKey(pemData)
pp := p.(*dsa.PrivateKey)
hashed := []byte{1}
sha256 := sha256.New()
sha256.Write(hashed)
hashed = sha256.Sum(nil)
r, s, _ := dsa.Sign(rand.Reader, pp, hashed)
type dsaSignature struct {
R, S *big.Int
}
var ss dsaSignature
ss.S = s
ss.R = r
signatureBytes, _ := asn1.Marshal(ss)
fmt.Println(hex.EncodeToString(signatureBytes))
}
Java
@Test
public void ttt() throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
String pubKey = "-----BEGIN PUBLIC KEY-----\n" +
"MIIBuDCCASwGByqGSM44BAEwggEfAoGBAP1/U4EddRIpUt9KnC7s5Of2EbdSPO9E\n" +
"AMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f\n" +
"6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv\n" +
"8iIDGZ3RSAHHAhUAl2BQjxUjC8yykrmCouuEC/BYHPUCgYEA9+GghdabPd7LvKtc\n" +
"NrhXuXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwky\n" +
"jMim4TwWeotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/h\n" +
"WuWfBpKLZl6Ae1UlZAFMO/7PSSoDgYUAAoGBAIb9o0KPsjAdzjK571e1Mx7ZhEyJ\n" +
"GrcxHiN2sW8IztEbqrKKiMxpNlTwm234uBdtzVHE3uDWZpfHPMIRmwBjCYDFRowW\n" +
"WVRdhdFXZlpCyp1gMWqJ11dh3FI3+O43DevRSyyuLRVCNQ1J3iVgwY5ndRpZU7n6\n" +
"y8DPH4/4EBT7KvnV\n" +
"-----END PUBLIC KEY-----";
String publicKeyPEM = pubKey
.replace("-----BEGIN PUBLIC KEY-----\n", "")
.replaceAll(System.lineSeparator(), "")
.replace("-----END PUBLIC KEY-----", "");
byte[] publicEncoded = Base64.decodeBase64(publicKeyPEM);
KeyFactory keyFactory1 = KeyFactory.getInstance("DSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicEncoded);
DSAPublicKey pubKeyy = (DSAPublicKey) keyFactory1.generatePublic(publicKeySpec);
Signature sig1 = Signature.getInstance("SHA256withDSA");
sig1.initVerify(pubKeyy);
byte[] orignData = new byte[]{1};
sig1.update(orignData);
boolean flag = sig1.verify(HexUtil.decodeHex("first step result"));
System.out.println(flag);
}
我在 java
中找到package sun.security.provider;
private BigInteger generateS(BigInteger var1, BigInteger var2, BigInteger var3, BigInteger var4) throws SignatureException {
byte[] var5;
try {
var5 = this.md.digest();
} catch (RuntimeException var9) {
throw new SignatureException(var9.getMessage());
}
// this line split the hash256 redsult
int var6 = var2.bitLength() / 8;
if (var6 < var5.length) {
var5 = Arrays.copyOfRange(var5, 0, var6);
}
BigInteger var7 = new BigInteger(1, var5);
BigInteger var8 = var4.modInverse(var2);
return var1.multiply(var3).add(var7).multiply(var8).mod(var2);
}
你可以在golang中使用
hashed := []byte{1}
sha256 := sha2562.New()
sha256.Write(hashed)
hashed = sha256.Sum(nil)
// you must split it
hashed = hashed[0:20]
原因是 sha256 结果在 java 中拆分,但 glang 没有拆分
遵循 FIPS186-4 第 4.6 和 4.7 节 golang
hashed := []byte{1}
pemData, _ := ioutil.ReadFile("config/secure/private.key")
p, err := ssh.ParseRawPrivateKey(pemData)
pp, ok := p.(*dsa.PrivateKey)
h := sha256.New()
h.Write(hashed)
hashed := h.Sum(nil)
if pp.Q.BitLen()/8 < len(hashed) {
hashed = hashed[0 : pp.Q.BitLen()/8]
}
r, s, _ := dsa.Sign(rand.Reader, pp, hashed)
var ss dsaSignature
ss.S = s
ss.R = r
hashed, _ = asn1.Marshal(ss)