ошибка дешифрования, возникающая при использовании RSA в Java. - PullRequest
0 голосов
/ 22 октября 2018

Моя цель - принять сообщение, содержащее запрос и источник.При получении этого сообщения должна быть сгенерирована пара ключей 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");
}

}

1 Ответ

0 голосов
/ 22 октября 2018

У вас есть несколько (много) проблем в вашем коде с шифрованием

Первое - правильно закодируйте ваши данные, строка в Java предназначена для представления печатных символов.Как только вы работаете с шифрованием (работая на уровне byte []), вам необходимо кодировать или декодировать значения.

Пример - ваш код выведет «keyHandle», это хеш объекта байтового массива, а нена самом деле сами зашифрованные данные

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

Используются в кодировке hex или base64 для распечатки вывода.То же относится и к подписи.

Я не могу решить ошибку расшифровки.

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

И вы просто предполагаете, что можете расшифровать некоторую случайную подстроку?Шифрование с использованием RSA приведет к выводу размера ключа (например, 2048 бит), и вы должны хранить и расшифровывать как целое, а не как любую подстроку.

В качестве учебного упражнения - попробуйте просто зашифровать и расшифровать, кодировать,расшифруйте, чтобы изучить примитивы, которые вы можете (повторно) использовать.

...