java - 在没有密码学库的情况下在 Java 中实现 DSA 的问题

标签 java security api dsa

你好,我有一个非常奇怪的问题,也许你们中的一些人可以帮助我。我正在 Java 中实现 DSA 签名算法,但除了从 java.security 生成 SHA-1 哈希函数外,我不能使用任何现有库来执行此操作。我的代码正在生成每个所需的数字,但验证签名时出现问题。这是我的代码:


    public class Key {
        int primeCenterie = 20;
        BigInteger q;
        BigInteger p;
        BigInteger g;
        BigInteger y;
        BigInteger x;
        BigInteger k;
        Random rand = new Random();
        Key() {        }
        public void generateKey() {
            q = new BigInteger(160, primeCenterie, rand);
            p = generateP(q, 512);
            g = generateG(p, q);
            do {
                x = new BigInteger(q.bitCount(), rand);
            } while (x.compareTo(BigInteger.ZERO) == -1 || x.compareTo(g) == 1);
            y = g.modPow(x, p);
            System.out.println("p:" + p);
            System.out.println("q:" + q);
            System.out.println("g:" + g);
            System.out.println("private key  (x):" + x);
            System.out.println("public key  (y):" + y);
        }
       private BigInteger generateP(BigInteger q, int l) {
            if (l % 64 != 0) {
                throw new IllegalArgumentException(" zle l ");
            }
            BigInteger pTemp;
            BigInteger pTemp2;
            do {
                pTemp = new BigInteger(l, primeCenterie, rand);
                pTemp2 = pTemp.subtract(BigInteger.ONE);
                pTemp = pTemp.subtract(pTemp2.remainder(q));
            } while (!pTemp.isProbablePrime(primeCenterie));
            return pTemp;
        }
        private BigInteger generateG(BigInteger p, BigInteger q) {
            BigInteger aux = p.subtract(BigInteger.ONE);
            BigInteger pow = aux.divide(q);
            BigInteger g;
            do {
                g = new BigInteger(aux.bitLength(), rand);
            } while (g.compareTo(aux) == -1 && g.compareTo(BigInteger.ZERO) == 1);
            return g.modPow(pow, aux);
        }
        public BigInteger generateR() {
            BigInteger r = g.modPow(x, p).mod(q);
            System.out.println("r:" + r);
            return r;
        }
        public BigInteger generateS(BigInteger r, byte[] data) {
            MessageDigest md;
            BigInteger s = BigInteger.ONE;
            try {
                md = MessageDigest.getInstance("SHA-1");
                md.update(data);
                BigInteger hash = new BigInteger(md.digest());
                System.out.println("Hash:" + hash);
                s = (x.modInverse(q).multiply(hash.add(x.multiply(r)))).mod(q);
            } catch (NoSuchAlgorithmException ex) {
                Logger.getLogger(DSA.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println("s:" + s);
            return s;
        }
        boolean verify(byte[] data, BigInteger r, BigInteger s) {
            if (r.compareTo(BigInteger.ZERO) <= 0 || r.compareTo(q) >= 0) {
                return false;
            }
            if (s.compareTo(BigInteger.ZERO) <= 0 || s.compareTo(q) >= 0) {
                return false;
            }
            MessageDigest md;
            BigInteger v = BigInteger.ZERO;
            try {
                md = MessageDigest.getInstance("SHA-1");
                md.update(data);
                BigInteger hash = new BigInteger(md.digest());
                BigInteger w = s.modInverse(q);
                BigInteger u1 = hash.multiply(w).mod(q);
                BigInteger u2 = r.multiply(w).mod(q);
                v = ((g.modPow(u1, p).multiply(y.modPow(u2, p))).mod(p)).mod(q);
            } catch (NoSuchAlgorithmException ex) {
                Logger.getLogger(DSA.class.getName()).log(Level.SEVERE, null, ex);
            }
            System.out.println("v:" + v);
            System.out.println("r:" + r);
            return v.compareTo(r) == 0;
        }
    }
我正在使用 generateR() 和 generateS(BigInteger r, byte[] data) 函数生成 R 和 S。数据是我的消息文本转换为字节。当我发送完全相同的字节数组并生成 S 和 R 来验证函数时,它返回 false。 R 和 V 不相同,但它们应该相同。我做错了什么:)?? 我以这个 c# 代码为例: http://www.koders.com/csharp/fidE9EF01A91C00DF066F023DD2EECA23856B922537.aspx?s=mdef%3Afile 和维基百科的描述 http://en.wikipedia.org/wiki/Digital_Signature_Algorithm

生成K的函数:


        public BigInteger generateK(BigInteger q){
            BigInteger tempK;
            do {
                tempK = new BigInteger(q.bitLength(), rand);
            } while (tempK.compareTo(q) != -1 && tempK.compareTo(BigInteger.ZERO) != 1);
            return tempK;
        }

最佳答案

终于!!这是我的代码:

public class Key {
   int primeCenterie = 20;
   BigInteger q;
   BigInteger p;
   BigInteger g;
   BigInteger y;
   BigInteger x;
   BigInteger k;
   Random rand = new Random();

Key() {}

public void generateKey() {
    q = new BigInteger(160, primeCenterie, rand);
    p = generateP(q, 512);
    g = generateG(p, q);
    do {
        x = new BigInteger(q.bitCount(), rand);
    } while (x.compareTo(BigInteger.ZERO) != 1 && x.compareTo(q) != -1);
    y = g.modPow(x, p);
}

private BigInteger generateP(BigInteger q, int l) {
    if (l % 64 != 0) {
        throw new IllegalArgumentException("L value is wrong");
    }
    BigInteger pTemp;
    BigInteger pTemp2;
    do {
        pTemp = new BigInteger(l, primeCenterie, rand);
        pTemp2 = pTemp.subtract(BigInteger.ONE);
        pTemp = pTemp.subtract(pTemp2.remainder(q));
    } while (!pTemp.isProbablePrime(primeCenterie) || pTemp.bitLength() != l);
    return pTemp;
}
private BigInteger generateG(BigInteger p, BigInteger q) {
    BigInteger aux = p.subtract(BigInteger.ONE);
    BigInteger pow = aux.divide(q);
    BigInteger gTemp;
    do {
        gTemp = new BigInteger(aux.bitLength(), rand);
    } while (gTemp.compareTo(aux) != -1 && gTemp.compareTo(BigInteger.ONE) != 1);
    return gTemp.modPow(pow, p);
}

public BigInteger generateK(BigInteger q) {
    BigInteger tempK;
    do {
        tempK = new BigInteger(q.bitLength(), rand);
    } while (tempK.compareTo(q) != -1 && tempK.compareTo(BigInteger.ZERO) != 1);
    return tempK;
}
public BigInteger generateR() {
    k = generateK(q);
    BigInteger r = g.modPow(k, p).mod(q);
    return r;
}

public BigInteger generateS(BigInteger r, byte[] data) {
    MessageDigest md;
    BigInteger s = BigInteger.ONE;
    try {
        md = MessageDigest.getInstance("SHA-1");
        md.update(data);
        BigInteger hash = new BigInteger(md.digest());
        s = (k.modInverse(q).multiply(hash.add(x.multiply(r)))).mod(q);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(DSA.class.getName()).log(Level.SEVERE, null, ex);
    }
    return s;
}

boolean verify(byte[] data, BigInteger r, BigInteger s) {
    if (r.compareTo(BigInteger.ZERO) <= 0 || r.compareTo(q) >= 0) {
        return false;
    }
    if (s.compareTo(BigInteger.ZERO) <= 0 || s.compareTo(q) >= 0) {
        return false;
    }
    MessageDigest md;
    BigInteger v = BigInteger.ZERO;
    try {
        md = MessageDigest.getInstance("SHA-1");
        md.update(data);
        BigInteger hash = new BigInteger(md.digest());
        BigInteger w = s.modInverse(q);
        BigInteger u1 = hash.multiply(w).mod(q);
        BigInteger u2 = r.multiply(w).mod(q);
        v = ((g.modPow(u1, p).multiply(y.modPow(u2, p))).mod(p)).mod(q);
    } catch (NoSuchAlgorithmException ex) {
        Logger.getLogger(DSA.class.getName()).log(Level.SEVERE, null, ex);
    }
    return v.compareTo(r) == 0;
}}

小错误但还是错误;)

@crazyscot 感谢您的帮助:D

关于java - 在没有密码学库的情况下在 Java 中实现 DSA 的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6005178/

相关文章:

Java 文本文件编码

java - 部分失败时的 executeBatch 行为

linux - 我的环境变量对系统上的其他用户安全吗?

.net - “未经授权的访问异常”- 'Global\.net clr networking'

sql - Dota2 - 是否可以通过 API 将私有(private)比赛信息获取到 sql 数据库中?

python - 如何显示 Clarifai API 搜索 Python 图像对象

java - 加载另一个类时 Jpanel 不绘制

java - 是否可以在一个 spring 容器中运行带有 spring security 的 spring webmvc webapp?

api - 股票市场API

java - 关闭 JTable 实例