2015-02-03 3 views
-1

У меня есть следующая проблема. У меня есть 2 функции в моем коде, которые предназначены для шифрования/расшифровки простой строки.Ошибка RSA-декодирования из-за строки ввода

SO:

Я должен передать строку "SomeString" функции:

public static String doEncryption(String input) { 


    try { 

     if (!RSAService.areKeysPresent()) { 
      RSAService.generateKey(); 
     } 


     ObjectInputStream inputStream; 

     // Encrypt the string using the public key 
     inputStream = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE)); 
     PublicKey publicKey = (PublicKey) inputStream.readObject(); 
     byte[] cipherText = RSAService.encrypt(input, publicKey); 
     return cipherText.toString(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return "ERROR: Public key file is probably missing"; 
} 

функция doEncryption("someString") возвращает "[B @ 61decc8c"

Теперь я нужно вставить эту строку в URL-адрес, а код на стороне сервера должен получить оттуда.

До сих пор это все хорошо, но когда я вызываю функцию

public static String doDecryption(String input) { 

      try { 

     if (!RSAService.areKeysPresent()) { 
      RSAService.generateKey(); 
     } 

     ObjectInputStream inputStream; 


     // Decrypt the cipher text using the private key. 
     inputStream = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE)); 
     PrivateKey privateKey = (PrivateKey) inputStream.readObject(); 
     String out = decrypt(input.getBytes(), privateKey); 
     return out; 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return "ERROR: Private key file is probably missing or doesn't match the public key"; 
} 

в doDecryption("[[email protected]") вопли со следующим исключением:

javax.crypto.BadPaddingException: Data must start with zero 
    at sun.security.rsa.RSAPadding.unpadV15(RSAPadding.java:325) 
    at sun.security.rsa.RSAPadding.unpad(RSAPadding.java:272) 
    at com.sun.crypto.provider.RSACipher.doFinal(RSACipher.java:356) 
    at com.sun.crypto.provider.RSACipher.engineDoFinal(RSACipher.java:382) 
    at javax.crypto.Cipher.doFinal(Cipher.java:2087) 
    at rsaendecryptor.RSAService.decrypt(RSAService.java:132) 
    at rsaendecryptor.RSAService.doDecryption(RSAService.java:180) 
    at rsaendecryptor.RSAEnDecrypt.main(RSAEnDecrypt.java:20) 
java.lang.NullPointerException 
    at java.lang.String.<init>(String.java:556) 
    at rsaendecryptor.RSAService.decrypt(RSAService.java:138) 
    at rsaendecryptor.RSAService.doDecryption(RSAService.java:180) 
    at rsaendecryptor.RSAEnDecrypt.main(RSAEnDecrypt.java:20) 

Есть ли способ, я могу обойти эту проблему? Мне нужно передать строку между клиентом и сервером, потому что они могут быть даже в разных доменах. Не говоря уже о том, что строка будет фактически сгенерирована из. Net-логики и отправлена ​​на сервер Java-сервера. Шифрование в строку отлично работает ... Что мне делать, чтобы исправить дешифрование.

Вот полный код класса:

public class RSAService { 

/** 
* String to hold name of the encryption algorithm. 
*/ 
public static final String ALGORITHM = "RSA"; 

/** 
* String to hold the name of the private key file. 
*/ 
public static final String PRIVATE_KEY_FILE = "private.key"; 

/** 
* String to hold name of the public key file. 
*/ 
public static final String PUBLIC_KEY_FILE = "public.key"; 

/** 
* Generate key which contains a pair of private and public key using 1024 
* bytes. Store the set of keys in Prvate.key and Public.key files. 
* 
*/ 
public static void generateKey() { 

    try { 
     final KeyPairGenerator keyGen = KeyPairGenerator.getInstance(ALGORITHM); 
     keyGen.initialize(1024); 
     final KeyPair key = keyGen.generateKeyPair(); 

     File privateKeyFile = new File(PRIVATE_KEY_FILE); 
     File publicKeyFile = new File(PUBLIC_KEY_FILE); 

     // Create files to store public and private key 
     privateKeyFile.createNewFile(); 

     if (publicKeyFile.getParentFile() != null) { 
      publicKeyFile.getParentFile().mkdirs(); 
     } 
     publicKeyFile.createNewFile(); 

     // Saving the Public key in a file 
     ObjectOutputStream publicKeyOS = new ObjectOutputStream(
       new FileOutputStream(publicKeyFile)); 
     publicKeyOS.writeObject(key.getPublic()); 
     publicKeyOS.close(); 

     // Saving the Private key in a file 
     ObjectOutputStream privateKeyOS = new ObjectOutputStream(
       new FileOutputStream(privateKeyFile)); 
     privateKeyOS.writeObject(key.getPrivate()); 
     privateKeyOS.close(); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 

} 

/** 
* The method checks if the pair of public and private key has been 
* generated. 
* 
* @return flag indicating if the pair of keys were generated. 
*/ 
public static boolean areKeysPresent() { 

    File privateKey = new File(PRIVATE_KEY_FILE); 
    File publicKey = new File(PUBLIC_KEY_FILE); 

    if (privateKey.exists() && publicKey.exists()) { 
     return true; 
    } 
    return false; 
} 

/** 
* Encrypt the plain text using public key. 
* 
* @param text : original plain text 
* @param key :The public key 
* @return Encrypted text 
* @throws java.lang.Exception 
*/ 
public static byte[] encrypt(String text, PublicKey key) { 
    byte[] cipherText = null; 
    try { 
     // get an RSA cipher object and print the provider 
     final Cipher cipher = Cipher.getInstance(ALGORITHM); 
     // encrypt the plain text using the public key 
     cipher.init(Cipher.ENCRYPT_MODE, key); 
     cipherText = cipher.doFinal(text.getBytes()); 
    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return cipherText; 
} 

/** 
* Decrypt text using private key. 
* 
* @param text :encrypted text 
* @param key :The private key 
* @return plain text 
* @throws java.lang.Exception 
*/ 
public static String decrypt(byte[] text, PrivateKey key) { 
    byte[] dectyptedText = null; 
    try { 
     // get an RSA cipher object and print the provider 
     final Cipher cipher = Cipher.getInstance(ALGORITHM); 

     // decrypt the text using the private key 
     cipher.init(Cipher.DECRYPT_MODE, key); 
     dectyptedText = cipher.doFinal(text); 

    } catch (Exception ex) { 
     ex.printStackTrace(); 
    } 

    return new String(dectyptedText); 
} 

public static String doEncryption(String input) { 


    try { 

     if (!RSAService.areKeysPresent()) { 
      RSAService.generateKey(); 
     } 


     ObjectInputStream inputStream; 

     // Encrypt the string using the public key 
     inputStream = new ObjectInputStream(new FileInputStream(PUBLIC_KEY_FILE)); 
     PublicKey publicKey = (PublicKey) inputStream.readObject(); 
     byte[] cipherText = RSAService.encrypt(input, publicKey); 
     return cipherText.toString(); 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return "ERROR: Public key file is probably missing"; 
} 


public static String doDecryption(String input) { 

      try { 

     if (!RSAService.areKeysPresent()) { 
      RSAService.generateKey(); 
     } 

     ObjectInputStream inputStream; 


     // Decrypt the cipher text using the private key. 
     inputStream = new ObjectInputStream(new FileInputStream(PRIVATE_KEY_FILE)); 
     PrivateKey privateKey = (PrivateKey) inputStream.readObject(); 
     String out = decrypt(input.getBytes(), privateKey); 
     return out; 

    } catch (Exception e) { 
     e.printStackTrace(); 
    } 
    return "ERROR: Private key file is probably missing or doesn't match the public key"; 
} 

}

+0

Вы возвращаете ciphertext.toString(), который, очевидно, даст хэш-код объекта шифрованного текста – shikjohari

+0

'cipherText.toString()' явно неверно. Используйте кодировку hex или Base64. – CodesInChaos

ответ

1
public static String doEncryption(String input) 

Остановитесь прямо там. Строка не является контейнером для двоичных данных и поэтому не должна была использоваться, чтобы содержать зашифрованный текст в первую очередь. Он должен был быть передан как byte[].

NB, когда вы получаете исключение, не угадайте, что это за условие, и верните строку, в которой говорится, что это «вероятно». Это делает отладочную догадку. Используйте сообщение, которое появилось с исключением.

0

Благодаря shikjohari и этой статье here я был в состоянии исправить мой код!

в методе doEncryption() я модифицировал возврат следующим образом:

return (Base64.encode(cipherText)).toString(); 

и doDecryption() метод, который я модифицировал возвращение следующим образом:

String out = decrypt(Base64.decode(input), privateKey); 
return out; 

Вы можете получить полный код из моего первого поста и просто отредактируйте возврат двух методов в соответствии с этим сообщением. Надеюсь это поможет.

Смежные вопросы