使用java签署文本文件并获取密钥并签名?

时间:2014-07-12 07:39:41

标签: java sign

我有一个文本文件,其中包含应用的版本号。我不确定整件事,因为我昨天遇到了这件事,我的英语不是最好的。这是我放在一起的代码(很好地复制了java tut):

public class FileValidator {

    public static void signFile(File file, File pkey, File sign) {
        try {
            KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
            SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
            keyGen.initialize(1024, random);
            KeyPair pair = keyGen.generateKeyPair();
            PrivateKey priv = pair.getPrivate();
            PublicKey pub = pair.getPublic();
            Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");
            dsa.initSign(priv);
            FileInputStream fis = new FileInputStream(file);
            BufferedInputStream bufin = new BufferedInputStream(fis);
            byte[] buffer = new byte[1024];
            int len;
            while ((len = bufin.read(buffer)) >= 0) {
                dsa.update(buffer, 0, len);
            }

            bufin.close();
            byte[] realSig = dsa.sign();

            // Save signature
            FileOutputStream sigfos = new FileOutputStream(sign);
            sigfos.write(realSig);
            sigfos.close();

            // Save public key
            byte[] key = pub.getEncoded();
            FileOutputStream keyfos = new FileOutputStream(pkey);
            keyfos.write(key);
            keyfos.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static boolean fileIsValid(File file, File pkey, File sign) {
        boolean verifies = false;
        try {
            FileInputStream keyfis = new FileInputStream(pkey);
            byte[] encKey = new byte[keyfis.available()];
            keyfis.read(encKey);

            keyfis.close();

            X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(encKey);
            KeyFactory keyFactory = KeyFactory.getInstance("DSA", "SUN");
            PublicKey pubKey = keyFactory.generatePublic(pubKeySpec);

            FileInputStream sigfis = new FileInputStream(sign);
            byte[] sigToVerify = new byte[sigfis.available()];
            sigfis.read(sigToVerify);
            sigfis.close();

            Signature sig = Signature.getInstance("SHA1withDSA", "SUN");
            sig.initVerify(pubKey);

            FileInputStream datafis = new FileInputStream(file);
            BufferedInputStream bufin = new BufferedInputStream(datafis);

            byte[] buffer = new byte[1024];
            int len;
            while (bufin.available() != 0) {
                len = bufin.read(buffer);
                sig.update(buffer, 0, len);
            }

            bufin.close();

            verifies = sig.verify(sigToVerify);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return verifies;
    }
}

我已经尝试过了,如果我修改了文件,它就可以了,fileIsValid()方法返回false。但是sign和pkey文件是本地的(意味着很容易修改)。我应该如何存放它们?在Web服务器上?我应该将它们存储在那里还是仅存储在标志上? (或者我可能只是误解了整个事情?)

1 个答案:

答案 0 :(得分:0)

要成功检查签名的有效性,所有三个部分(文件,公钥,签名)必须合在一起。如果你被允许改变这三个,你当然可以拿出通过测试的其他三元组。

如果您无法更改公钥并且您没有私钥,则几乎不可能生成另一个通过的文件签名组合。

这取决于用例存储在哪里。如果要确保下载的文件未被篡改,通常会以受信任的方式从受信任的来源获取公钥,然后检查签名的有效性。如果通过,您可以非常确定私钥的所有者已经签署了文件,并且之后没有更改。