首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Go DSA与Java DSA的区别

Go DSA与Java DSA的区别
EN

Stack Overflow用户
提问于 2021-09-01 07:44:52
回答 1查看 140关注 0票数 1
  1. Go使用DSA私钥
  2. 来生成签名,使用DSA公钥验证第一步的结果
  3. 应返回true,但返回false

代码语言:javascript
复制
package main
import (
    "crypto/dsa"
    "crypto/rand"
    "encoding/asn1"
    "encoding/hex"
    "fmt"
    "golang.org/x/crypto/ssh"
    "math/big"
)

func main() {
    // a dsa private key
    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-----")
    // parse dsa 
    p, _ := ssh.ParseRawPrivateKey(pemData)
    pp := p.(*dsa.PrivateKey)

    // orign data
    hashed := []byte{1}
    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)

    // print sign 
    fmt.Println(hex.EncodeToString(signatureBytes))
}

  1. Java读取DSA公钥并初始化signer
  2. Java验证第一步符号result
  3. returns false

代码语言:javascript
复制
@Test
public void ttt() throws InvalidKeySpecException, NoSuchAlgorithmException, InvalidKeyException, SignatureException {
        // DSA public key
        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);

        // init signer
        Signature sig1 = Signature.getInstance("DSA");
        sig1.initVerify(pubKeyy);
        sig1.update(new byte[]{1});
        
        // verify first result
        System.out.println(sig1.verify(HexUtil.decodeHex("first step result")));
}

  1. i尝试在Java实现中使用 NONEwithDSA ,但它没有执行it
  2. Signature sig1 = Signature.getInstance("NONEwithDSA");

代码语言:javascript
复制
java.security.SignatureException: Data for RawDSA must be exactly 20 bytes long

  1. i尝试在Java实现中使用 SHA1withDSA ,但它没有执行it
  2. Signature sig1 = Signature.getInstance("SHA1withDSA");
  3. returns false
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-09-01 12:20:44

在Java中,(签名)算法名DSASHA1withDSA的别名,即最初的FIPS186-0算法。这是,与Go显然实现的非标准的“raw”原始不一样。NONEwithDSA确实是您想要的东西的正确的Java名称,但是在“标准”(SUN)提供程序中的实现是某种程度上只需要20字节的数据,而不是或多或少的,因为这就是SHA1哈希的大小,这是FIPS186-3之前SHA1的唯一标准哈希。

如果您(拥有或可以获取和)使用BouncyCastle提供程序,则它没有此限制,并且应该适用于更改为NONEwithDSA的代码(当然,可以修改代码或安全配置,以便选择BC作为提供程序)。

如果您不使用Bouncy,我认为您必须自己编写算法;我认为没有任何方法可以让SUN实现来做您想做的事情。

虽然最好按照标准中指定的适当大小的散列签名,而不是原始数据,但是您可以按照指定和设计使用Java提供程序。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69009710

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档