【发布时间】:2015-08-02 07:56:48
【问题描述】:
我正在尝试使用私钥对加密消息进行签名并在 Java 中对其进行验证。这是我第一次使用加密和签名,所以我不确定它应该如何工作,我有点卡在这里。验证总是返回 false。
我在这里发布代码,其中包括最重要的部分:
import android.util.Base64;
import android.util.Log;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateKeySpec;
import java.security.spec.RSAPublicKeySpec;
public class SignatureTest {
// testing signature
PublicKey javaPublicKey;
PrivateKey javaPrivateKey;
String message = "Hello world";
public void test() {
try {
GenerateKeys();
byte[] messageBytes = message.getBytes("UTF-8");
byte[] signature = rsaSign(messageBytes);
boolean success = rsaVerify(messageBytes, signature);
if(success){
Log.e("yay", "yay");
}
else {
Log.e("nay", "nay");
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
public void GenerateKeys() {
SecureRandom random = null;
try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
random = SecureRandom.getInstance("SHA1PRNG");
keyGen.initialize(1024, random);
KeyPair pair = keyGen.generateKeyPair();
javaPrivateKey = pair.getPrivate();
javaPublicKey = pair.getPublic();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
}
public byte[] rsaSign (byte[] data) {
byte[] cipherData = null;
try {
Signature s = Signature.getInstance("SHA1withRSA");
s.initSign(javaPrivateKey);
s.update(data);
Log.e("s.sign()", Base64.encodeToString(s.sign(), Base64.DEFAULT));
return s.sign();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
}
return cipherData;
}
public boolean rsaVerify (byte[] data, byte[] signature) {
boolean success = false;
try {
Signature s = Signature.getInstance("SHA1withRSA");
s.initVerify(javaPublicKey);
s.update(data);
success = s.verify(Base64.decode(signature, Base64.DEFAULT));
if(success == true) {
Log.i("yeay", "yay");
}
else {
Log.i("nay", "nay");
}
return success;
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (InvalidKeyException e) {
e.printStackTrace();
} catch (SignatureException e) {
e.printStackTrace();
}
return false;
}
}
谁能告诉我我在这里做错了什么?
【问题讨论】:
-
至少告诉我你为什么不赞成这篇文章
-
确保您的主题不是重复的,并尝试缩小代码中可能特定于错误的区域。 Stack 是关于提出非常具体的问题,不一定用于一般的代码审查。我敢肯定你有一个很好的问题埋在那里,把它挖出来!它就像一块大理石,只需要再移除一点......
-
谢谢。我确实缩小了范围,但试图复制/粘贴代码并直接运行它。问题是我不知道问题出在代码中。任何一条线都可能是问题所在。不过谢谢,我会做更多的研究。
-
是的!堆栈往往非常至关重要,因此请确保您在发布之前已经完成了一些功课(并不是说您没有!)。但是不要气馁,社区非常适合答案,您只需要小心处理它。祝你好运!
-
您在 verify 函数中进行了 base64 解码,但签名一开始就从未进行过 base64 编码。此外,您不能重复调用 Signature.sign() 因为结果未缓存在 Signature 对象中。您必须调用一次并自己保存结果。
标签: java android rsa digital-signature public-key-encryption