Java 如何使用私钥对字符串进行签名
如果我已经将私钥设置为Java 如何使用私钥对字符串进行签名,java,digital-signature,private-key,sign,public-key,Java,Digital Signature,Private Key,Sign,Public Key,如果我已经将私钥设置为byte[]或string,那么如何使用SHA1withRSA获取字符串签名?我想你说的是,你已经知道密钥对了,想用它签名/验证 请参阅以下代码 import java.security.KeyPair; import java.security.KeyPairGenerator; import java.security.NoSuchAlgorithmException; import java.security.Signature; import sun.misc.B
byte[]
或string
,那么如何使用SHA1withRSA
获取字符串签名?我想你说的是,你已经知道密钥对了,想用它签名/验证
请参阅以下代码
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.NoSuchAlgorithmException;
import java.security.Signature;
import sun.misc.BASE64Encoder;
public class MainClass {
public static void main(String[] args) throws Exception {
KeyPair keyPair = getKeyPair();
byte[] data = "test".getBytes("UTF8");
Signature sig = Signature.getInstance("SHA1WithRSA");
sig.initSign(keyPair.getPrivate());
sig.update(data);
byte[] signatureBytes = sig.sign();
System.out.println("Signature:" + new BASE64Encoder().encode(signatureBytes));
sig.initVerify(keyPair.getPublic());
sig.update(data);
System.out.println(sig.verify(signatureBytes));
}
private static KeyPair getKeyPair() throws NoSuchAlgorithmException {
KeyPairGenerator kpg = KeyPairGenerator.getInstance("RSA");
kpg.initialize(1024);
return kpg.genKeyPair();
}
}
这里您需要更改getKeyPair()方法以提供已知的密钥对。您可以从java密钥存储[JKS]加载它
您不能将任意字节数组作为公钥或私钥。它们应该根据关系生成。首先必须从字节数组中创建公钥
byte publicKeyBytes[] = .... your public key in bytes ...
KeyFactory keyFactory = KeyFactory.getInstance("RSA");
X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes));
PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
在使用公钥加密之后
String data = "... data to be encrypted ....";
String alg = "RSA/ECB/PKCS1Padding";
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
byte encryptedBytes[] = cipher.doFinal(data.getBytes());
现在只有拥有私钥的人才可以读取您的数据
@rczajka:公钥是一把钥匙。您可以使用它对只有所有者(拥有私钥)才能读取的内容进行签名。我使用它对数据进行签名和验证
您应该添加maven依赖项:
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.56</version>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
<version>1.56</version>
</dependency>
创建RSA数字签名
// GIVEN: InputStream prvKeyInpStream
AsymmetricKeyParameter privKey = KeyUtil.loadPrivateKey(prvKeyInpStream);
// GIVEN: byte[] messageBytes = ...
RSADigestSigner signer = new RSADigestSigner(new SHA512Digest());
signer.init(true, privKey);
signer.update(messageBytes, 0, messageBytes.length);
try {
byte[] signature = signer.generateSignature();
} catch (Exception ex) {
throw new RuntimeException("Cannot generate RSA signature. " + ex.getMessage(), ex);
}
// GIVEN: InputStream pubKeyInpStream
AsymmetricKeyParameter publKey = KeyUtil.loadPublicKey(pubKeyInpStream);
// GIVEN: byte[] messageBytes
RSADigestSigner signer = new RSADigestSigner(new SHA512Digest());
signer.init(false, publKey);
signer.update(messageBytes, 0, messageBytes.length);
// GIVEN: byte[] signature - see code sample above
boolean isValidSignature = signer.verifySignature(signature);
验证RSA数字签名
// GIVEN: InputStream prvKeyInpStream
AsymmetricKeyParameter privKey = KeyUtil.loadPrivateKey(prvKeyInpStream);
// GIVEN: byte[] messageBytes = ...
RSADigestSigner signer = new RSADigestSigner(new SHA512Digest());
signer.init(true, privKey);
signer.update(messageBytes, 0, messageBytes.length);
try {
byte[] signature = signer.generateSignature();
} catch (Exception ex) {
throw new RuntimeException("Cannot generate RSA signature. " + ex.getMessage(), ex);
}
// GIVEN: InputStream pubKeyInpStream
AsymmetricKeyParameter publKey = KeyUtil.loadPublicKey(pubKeyInpStream);
// GIVEN: byte[] messageBytes
RSADigestSigner signer = new RSADigestSigner(new SHA512Digest());
signer.init(false, publKey);
signer.update(messageBytes, 0, messageBytes.length);
// GIVEN: byte[] signature - see code sample above
boolean isValidSignature = signer.verifySignature(signature);
不能使用公钥对任何内容进行签名。公钥只能用于读取邮件,但不能使用公钥对新邮件进行签名。私钥可以用来对消息进行签名。上面的两个注释实际上不是真的(通常)。通常,您可以使用密钥(私有或公共)对内容进行加密(并因此对其进行签名)。这就是非对称加密的工作原理。如果Bob想向Alice发送加密的消息,他实际上使用Alice的公钥加密他的消息,而Alice将使用她的私钥解密。如果他还想对消息进行签名,他将使用他的私钥对消息的散列进行加密,Alice使用Bob的公钥对该散列进行解密,并根据收到的消息进行验证。他问的不是如何加密数据,而是如何对数据进行签名。加密!=signHi Durga,欢迎来到SO。在答案中发布代码片段真的很好。如果你再加一点解释就更好了。不过,感谢您的第一次贡献!
public static String sign(String plainText, PrivateKey privateKey) throws Exception {
Signature privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(privateKey);
privateSignature.update(plainText.getBytes(UTF_8));
byte[] signature = privateSignature.sign();
return Base64.getEncoder().encodeToString(signature);
}
public static boolean verify(String plainText, String signature, PublicKey publicKey) throws Exception {
Signature publicSignature = Signature.getInstance("SHA256withRSA");
publicSignature.initVerify(publicKey);
publicSignature.update(plainText.getBytes(UTF_8));
byte[] signatureBytes = Base64.getDecoder().decode(signature);
return publicSignature.verify(signatureBytes);
}