2014-10-08 203 views
0

我已经加载了两个密钥,并且我想在与其中一个签名后验证它们,但是我遇到了困难。最后我得到“验证:错误”,没有任何错误。有人可以指出缺陷吗?验证私钥和公钥RSA密钥匹配

package fliesigning; 

import static fliesigning.FlieSigning.verifySig; 
import java.io.*; 
import java.nio.ByteBuffer; 
import java.security.*; 
import java.security.spec.PKCS8EncodedKeySpec; 
import java.security.spec.X509EncodedKeySpec; 
import java.math.BigInteger; 
import java.security.Provider; 
import java.security.Security; 
import java.security.interfaces.RSAPrivateKey; 
import java.security.interfaces.RSAPublicKey; 
import java.security.spec.RSAPrivateKeySpec; 
import java.security.spec.RSAPublicKeySpec; 
import javax.crypto.Cipher; 
import org.apache.commons.codec.binary.Base64; 

public class Signing { 
    private static final String BEGIN_RSA_PRIVATE_KEY = "<PRIVATE KEY>"; 
    private static final String BEGIN_RSA_PUBLIC_KEY = "<PUBLIC KEY>"; 

    public static void main(String[] args) throws Exception { 
    // Remove the first and last lines 
    String privKeyPEM = BEGIN_RSA_PRIVATE_KEY.replace("-----BEGIN RSA PRIVATE KEY-----\n", ""); 
    privKeyPEM = privKeyPEM.replace("-----END RSA PRIVATE KEY-----", ""); 
    System.out.println(privKeyPEM); 

    String publicKeyPEM = BEGIN_RSA_PUBLIC_KEY.replace("-----BEGIN PUBLIC KEY-----\n", ""); 
    publicKeyPEM = publicKeyPEM.replace("-----END PUBLIC KEY-----", ""); 
    System.out.println(publicKeyPEM); 

    // Base64 decode the data 
    Base64 b64 = new Base64(); 
    byte [] encoded = b64.decode(privKeyPEM); 
    byte [] encoded_pub = b64.decode(publicKeyPEM); 

    // PKCS8 decode the encoded RSA private key 
    PKCS8EncodedKeySpec privateKeySpec = new PKCS8EncodedKeySpec(encoded); 
    KeyFactory kf = KeyFactory.getInstance("RSA"); 
    PrivateKey privKey = kf.generatePrivate(privateKeySpec); 

    X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(encoded_pub); 
    KeyFactory pk = KeyFactory.getInstance("RSA"); 
    PublicKey publicKey = pk.generatePublic(publicKeySpec); 

    // Display the results 
    System.out.println(privKey); 
    String file = "qwerty"; 
    byte[] fileBytes = file.getBytes(); 
    byte[] digitalSignature = signData(fileBytes, privKey); 
    System.out.println("SIGNATURE MADE"); 
    boolean verified; 
    verified = verifySig(fileBytes, publicKey, digitalSignature); 
    System.out.println("verified: " + verified) ; 
    } 

    public static byte[] signData(byte[] data, PrivateKey key) throws Exception { 
    Signature signer = Signature.getInstance("SHA256withRSA"); 
    signer.initSign(key); 
    signer.update(data); 
    return (signer.sign()); 
    } 

    public static boolean verifySig(byte[] data, PublicKey key, byte[] sig) throws Exception { 
    Signature signer = Signature.getInstance("SHA256withRSA"); 
    signer.initVerify(key); 
    signer.update(data); 
    return (signer.verify(sig)); 
    } 
} 

回答

1

您的代码似乎正常工作,它必须是您的密钥实际上不匹配。

  • openssl genrsa -out priv.pem
    (创建基本的RSA私钥)

  • openssl rsa -in priv.pem -pubout -out pub.pem
    (提取公钥)

  • openssl pkcs8 -in priv.pem -out pk8.pem -topk8 -nocrypt
    :我使用创造了一些测试键(兑换 私钥加密到PKCS#8格式)

这给了我两个文件来进行测试:pk8.pempub.pem。我稍微更改了代码,以便开始和结束标记分别为-----BEGIN PRIVATE KEY----------END PRIVATE KEY-----

验证通过成功。

+0

嗯,它的作品,谢谢!只是想问一下,我是否可以以某种方式优化代码,使其更好? – 2014-10-08 13:29:30

+0

另一个问题,我怎样才能从文件而不是字符串中读取密钥? – 2014-10-08 13:39:16

+0

@davidguetta你的第一个问题可能适用于http://codereview.stackexchange.com。在发布之前请检查帮助页面。对于第二个问题,我认为Google会帮助你。 – 2014-10-08 13:42:16