我有一个文本文件,其中包含应用的版本号。我不确定整件事,因为我昨天遇到了这件事,我的英语不是最好的。这是我放在一起的代码(很好地复制了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服务器上?我应该将它们存储在那里还是仅存储在标志上? (或者我可能只是误解了整个事情?)
答案 0 :(得分:0)
要成功检查签名的有效性,所有三个部分(文件,公钥,签名)必须合在一起。如果你被允许改变这三个,你当然可以拿出通过测试的其他三元组。
如果您无法更改公钥并且您没有私钥,则几乎不可能生成另一个通过的文件签名组合。
这取决于用例存储在哪里。如果要确保下载的文件未被篡改,通常会以受信任的方式从受信任的来源获取公钥,然后检查签名的有效性。如果通过,您可以非常确定私钥的所有者已经签署了文件,并且之后没有更改。