How to sign string with private key

后端 未结 5 2047
别那么骄傲
别那么骄傲 2020-12-04 18:02

How can I get the signature of a string using SHA1withRSA if I already have the Private Key as byte[] or String?

相关标签:
5条回答
  • 2020-12-04 18:52
    public static String sign(String samlResponseString, String keystoreFile, String keyStorePassword, String privateKeyPassword, String alias)
                throws NoSuchAlgorithmException, UnsupportedEncodingException,
                InvalidKeyException, SignatureException {
            PrivateKey pkey=getPrivateKey(  keystoreFile,   keyStorePassword, privateKeyPassword,   alias);
            String signedString = null;
            Signature signature = Signature.getInstance("SHA256withRSA");
            signature.initSign(pkey);
            signature.update(samlResponseString.getBytes());
            byte[] signatureBytes = signature.sign();
            byte[] encryptedByteValue = Base64.encodeBase64(signatureBytes);
            signedString = new String(encryptedByteValue, "UTF-8");
            System.out.println(signedString);
            return signedString;
        }
    
    0 讨论(0)
  • 2020-12-04 19:00
    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);
    }
    
    0 讨论(0)
  • 2020-12-04 19:02

    I guess what you say is you know the key pair before hand and want to sign/verify with that.

    Please see the following code.

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

    Here you need to change the method getKeyPair() to supply your known key pair. You may load it from a java key store [JKS].

    You can't just have an arbitrary byte array either as your public key or private key. They should be generated in relation.

    0 讨论(0)
  • 2020-12-04 19:04

    I use bouncy-castle to sign data and verify it.

    you should add maven dependency:

    <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>
    

    Load RSA private or public key from a disk file into a Java object

    First, we need to be able to load RSA private or public key from a disk file into a Java object of a proper class from Bouncy Castle

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import org.apache.commons.lang3.Validate;
    import org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
    import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
    import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
    import org.bouncycastle.crypto.util.PrivateKeyFactory;
    import org.bouncycastle.crypto.util.PublicKeyFactory;
    import org.bouncycastle.openssl.PEMKeyPair;
    import org.bouncycastle.openssl.PEMParser;
    
    public class KeyUtil {
    
        public static AsymmetricKeyParameter loadPublicKey(InputStream is) {
            SubjectPublicKeyInfo spki = (SubjectPublicKeyInfo) readPemObject(is);
            try {
                return PublicKeyFactory.createKey(spki);
            } catch (IOException ex) {
                throw new RuntimeException("Cannot create public key object based on input data", ex);
            }
        }
    
        public static AsymmetricKeyParameter loadPrivateKey(InputStream is) {
            PEMKeyPair keyPair = (PEMKeyPair) readPemObject(is);
            PrivateKeyInfo pki = keyPair.getPrivateKeyInfo();
            try {
                return PrivateKeyFactory.createKey(pki);
            } catch (IOException ex) {
                throw new RuntimeException("Cannot create private key object based on input data", ex);
            }
        }
    
        private static Object readPemObject(InputStream is) {
            try {
                Validate.notNull(is, "Input data stream cannot be null");
                InputStreamReader isr = new InputStreamReader(is, "UTF-8");
                PEMParser pemParser = new PEMParser(isr);
    
                Object obj = pemParser.readObject();
                if (obj == null) {
                    throw new Exception("No PEM object found");
                }
                return obj;
            } catch (Throwable ex) {
                throw new RuntimeException("Cannot read PEM object from input data", ex);
            }
        }
    }
    

    Creation of an RSA digital signature

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

    Verification of an RSA digital signature

    // 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);
    
    0 讨论(0)
  • 2020-12-04 19:06

    You first must create a public key from array of bytes

    byte publicKeyBytes[] = .... your public key in bytes ... 
    KeyFactory keyFactory = KeyFactory.getInstance("RSA"); 
    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(publicKeyBytes)); 
    PublicKey publicKey = keyFactory.generatePublic(publicKeySpec);
    

    and after using the publicKey to encrypt

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

    Now only who have the privateKey can read your data

    @rczajka: a publicKey is a key. You can use it to sign somethig that only the owner (that have the privateKey) can read.

    0 讨论(0)
提交回复
热议问题