Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用私钥对字符串进行签名_Java_Digital Signature_Private Key_Sign_Public Key - Fatal编程技术网

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);
}