簡體   English   中英

在Java中使用rsa時發生解密錯誤。

[英]decryption error occurring when using rsa in java.

我的目的是接受包含挑戰和起源的信息。 收到此消息后,必須生成一個rsa密鑰對,然后將其用於操作數據,如下所示。 數據的某些部分使用生成的公共密鑰加密。 授權期間,必須使用私鑰解密該數據。 但是,當我嘗試解密時,顯示解密錯誤。 我什至已經打印了代碼的不同部分,只是為了檢查是否實現了所需的輸出,這就是為什么我知道從文件中獲取的私鑰是正確的。 我無法解決解密錯誤。 該任務的規范要求使用rsa,而不是混合加密。 我曾嘗試填充,但這並沒有幫助。 請咨詢如何解決這個問題

package pam;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;

import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.xml.bind.DatatypeConverter;
import com.sun.jersey.core.util.Base64;

class Test 
{
  public static void kpgen(int numBits, String s) throws Exception
  {
    if(s.length()!=64)
    {
        System.out.println("invalid entry");
    }
    else
    {
        KeyPairGenerator keygen = KeyPairGenerator.getInstance("RSA");
        KeyPair keyPair = keygen.genKeyPair();
        PrivateKey privateKey = keyPair.getPrivate();
        PublicKey publicKey = keyPair.getPublic();
        System.out.println("pk: "+privateKey);
        System.out.println("pubk: "+publicKey);

        String fileBase = "f:\\tempKey";        //WRITING PVT KEY TO FILE
        try (FileOutputStream out = new FileOutputStream(fileBase + ".key")) 
        {
            out.write(keyPair.getPrivate().getEncoded());
        }
        try (FileOutputStream out = new FileOutputStream(fileBase + ".pub")) 
{
            out.write(keyPair.getPublic().getEncoded());
        }

        System.out.println("Key pair : " + Base64.encode(String.valueOf(keyPair)));
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        byte[] digest = md.digest(keyPair.toString().getBytes(StandardCharsets.UTF_8));
        String sha256 = DatatypeConverter.printHexBinary(digest).toLowerCase();
        System.out.println("Hash value: "+sha256);

        String ch = s.substring(0,32);
        String or = s.substring(32,64);
        System.out.println("Challenge: "+ch);
        System.out.println("Origin: "+or);

        MessageDigest md1 = MessageDigest.getInstance("SHA-256");
        byte[] digest1 = md1.digest(privateKey.toString().getBytes(StandardCharsets.UTF_8));
        String sha = DatatypeConverter.printHexBinary(digest1).toLowerCase();
        or = or + sha;
        System.out.println("String kh: "+or);

        Cipher cipher = Cipher.getInstance("RSA");  
        cipher.init(Cipher.ENCRYPT_MODE, publicKey);
        byte[] keyHandle = cipher.doFinal(or.getBytes());
        System.out.println("Key Handle: "+keyHandle);

        String f = "f:\\keyList.pub";
        Key pub = getKeyFromFile(f);
        System.out.println("Attestation Public Key: "+pub);

        PrivateKey pk = (PrivateKey) getPvtKey("f:\\keyList.key");
        Signature rsa = Signature.getInstance("SHA1withRSA"); 
        rsa.initSign(pk);
        rsa.update(ch.getBytes());
        byte[] sc = rsa.sign();
        System.out.println("Signed challenge: "+sc);

        String rm = publicKey.toString() + pub + sc + keyHandle;
        System.out.println("Response Msg: " +rm);
    }
}
public static Key getKeyFromFile(String fileName) throws Exception
{
    byte[] bytes = Files.readAllBytes(Paths.get(fileName));
    X509EncodedKeySpec ks = new X509EncodedKeySpec(bytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PublicKey pub = kf.generatePublic(ks);
    return pub;
}
public static PrivateKey getPvtKey(String s) throws IOException, NoSuchAlgorithmException, InvalidKeySpecException
{
    byte[] bytes = Files.readAllBytes(Paths.get(s));
    PKCS8EncodedKeySpec ks = new PKCS8EncodedKeySpec(bytes);
    KeyFactory kf = KeyFactory.getInstance("RSA");
    PrivateKey pvt = kf.generatePrivate(ks);
    return pvt;
}
public static void auth(String s) throws NoSuchAlgorithmException, Exception, IOException
{   
    String chal = s.substring(0, 32);
    String origin = s.substring(32,64);
    String kh = s.substring(64);
    byte[] kh1 = kh.getBytes();

    PrivateKey pvtKey = getPvtKey("f:\\tempKey.key"); //READING THE PRIVATE KEY MADE IN KPGEN
    System.out.println("pk: "+pvtKey);
    Cipher cipher = Cipher.getInstance("RSA");  
    cipher.init(Cipher.DECRYPT_MODE, pvtKey);
    byte[] keyHandle = cipher.doFinal(kh1);

    String or = keyHandle.toString().substring(0, (kh.length()/2));
    String pk = keyHandle.toString().substring(kh.length()/2);

    int c = 0;
    if(or.equals(origin))
    {
        c++;
    }
    else
    {
        System.out.println("Bad Key Handle: Invalid Origin");
    }
    if(pk.equals(pvtKey.toString()))
    {
        c++;
    }
    else
    {
        System.out.println("Bad Key Handle: invalid private key");
    }
    if(c==2)
    {
        Signature rsa = Signature.getInstance("SHA1withRSA"); 
        rsa.initSign((PrivateKey) pvtKey);
        rsa.update(chal.getBytes());
        byte[] sc = rsa.sign();
        System.out.println("Signed Challenge: "+sc);
    }
    else
        System.out.println("error");
}

}

加密中的代碼中有多個(很多)問題

首先-正確編碼您的數據,Java中的String表示可打印字符。 一旦使用加密(在byte []級別上工作),就需要對值進行編碼或解碼。

示例-您的代碼將打印“ keyHandle”,這是一個字節數組對象哈希,不是真正的加密數據本身

byte[] keyHandle = cipher.doFinal(or.getBytes());
System.out.println("Key Handle: "+keyHandle);
...
String rm = publicKey.toString() + pub + sc + keyHandle;

用於十六進制或base64編碼以打印輸出。 簽名也是如此。

我無法解決解密錯誤。

String kh = s.substring(64);
byte[] kh1 = kh.getBytes();
..  
byte[] keyHandle = cipher.doFinal(kh1);

您只是假設您可以解密一些隨機子串? 使用RSA加密將產生密鑰大小的輸出(例如2048位),您必須整體存儲和解密,而不要存儲任何子字符串。

作為學習練習,請嘗試簡單地加密和解密,編碼,解碼,以學習可以(重復)使用的原語。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM