Considérer:
import Java.awt.*;
import javax.swing.*;
import Java.awt.event.*;
import javax.crypto.*;
import javax.crypto.spec.*;
import Java.security.*;
import Java.io.*;
public class EncryptURL extends JApplet implements ActionListener {
Container content;
JTextField userName = new JTextField();
JTextField firstName = new JTextField();
JTextField lastName = new JTextField();
JTextField email = new JTextField();
JTextField phone = new JTextField();
JTextField heartbeatID = new JTextField();
JTextField regionCode = new JTextField();
JTextField retRegionCode = new JTextField();
JTextField encryptedTextField = new JTextField();
JPanel finishPanel = new JPanel();
public void init() {
//setTitle("Book - E Project");
setSize(800, 600);
content = getContentPane();
content.setBackground(Color.yellow);
content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
JButton submit = new JButton("Submit");
content.add(new JLabel("User Name"));
content.add(userName);
content.add(new JLabel("First Name"));
content.add(firstName);
content.add(new JLabel("Last Name"));
content.add(lastName);
content.add(new JLabel("Email"));
content.add(email);
content.add(new JLabel("Phone"));
content.add(phone);
content.add(new JLabel("HeartBeatID"));
content.add(heartbeatID);
content.add(new JLabel("Region Code"));
content.add(regionCode);
content.add(new JLabel("RetRegionCode"));
content.add(retRegionCode);
content.add(submit);
submit.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand() == "Submit"){
String subUserName = userName.getText();
String subFName = firstName.getText();
String subLName = lastName.getText();
String subEmail = email.getText();
String subPhone = phone.getText();
String subHeartbeatID = heartbeatID.getText();
String subRegionCode = regionCode.getText();
String subRetRegionCode = retRegionCode.getText();
String concatURL =
"user=" + subUserName + "&f=" + subFName +
"&l=" + subLName + "&em=" + subEmail +
"&p=" + subPhone + "&h=" + subHeartbeatID +
"&re=" + subRegionCode + "&ret=" + subRetRegionCode;
concatURL = padString(concatURL, ' ', 16);
byte[] encrypted = encrypt(concatURL);
String encryptedString = bytesToHex(encrypted);
content.removeAll();
content.add(new JLabel("Concatenated User Input -->" + concatURL));
content.add(encryptedTextField);
setContentPane(content);
}
}
public static byte[] encrypt(String toEncrypt) throws Exception{
try{
String plaintext = toEncrypt;
String key = "01234567890abcde";
String iv = "fedcba9876543210";
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, keyspec, ivspec);
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;
}
catch(Exception e){
}
}
public static byte[] decrypt(byte[] toDecrypt) throws Exception{
String key = "01234567890abcde";
String iv = "fedcba9876543210";
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.DECRYPT_MODE, keyspec, ivspec);
byte[] decrypted = cipher.doFinal(toDecrypt);
return decrypted;
}
public static String bytesToHex(byte[] data) {
if (data == null)
{
return null;
}
else
{
int len = data.length;
String str = "";
for (int i=0; i<len; i++)
{
if ((data[i]&0xFF) < 16)
str = str + "0" + Java.lang.Integer.toHexString(data[i]&0xFF);
else
str = str + Java.lang.Integer.toHexString(data[i]&0xFF);
}
return str;
}
}
public static String padString(String source, char paddingChar, int size)
{
int padLength = size-source.length() % size;
for (int i = 0; i < padLength; i++) {
source += paddingChar;
}
return source;
}
}
Je reçois une exception non signalée:
Java.lang.Exception; must be caught or declared to be thrown
byte[] encrypted = encrypt(concatURL);
Aussi bien que:
.Java:109: missing return statement
Comment résoudre ces problèmes?
Tous vos problèmes en découlent
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;
Qui sont enfermés dans un bloc try, catch, le problème est que si le programme a trouvé une exception, vous ne retournez rien. Mettez-le comme ceci (modifiez-le selon la logique de votre programme):
public static byte[] encrypt(String toEncrypt) throws Exception{
try{
String plaintext = toEncrypt;
String key = "01234567890abcde";
String iv = "fedcba9876543210";
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE,keyspec,ivspec);
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;
} catch(Exception e){
return null; // Always must return something
}
}
Pour le second, vous devez intercepter l'exception de l'appel de méthode encrypt , comme ceci (modifiez-le également en fonction de la logique de votre programme):
public void actionPerformed(ActionEvent e)
.
.
.
try {
byte[] encrypted = encrypt(concatURL);
String encryptedString = bytesToHex(encrypted);
content.removeAll();
content.add(new JLabel("Concatenated User Input -->" + concatURL));
content.add(encryptedTextField);
setContentPane(content);
} catch (Exception exc) {
// TODO: handle exception
}
}
Les leçons que vous devez en tirer:
Le problème est dans cette méthode:
public static byte[] encrypt(String toEncrypt) throws Exception{
C'est le signature de méthode qui dit à peu près:
Dans ce cas, la signature de la méthode indique que lorsqu'elle est invoquée, cette méthode "pourrait" potentiellement lever une exception de type "Exception".
....
concatURL = padString(concatURL, ' ', 16);
byte[] encrypted = encrypt(concatURL); <-- HERE!!!!!
String encryptedString = bytesToHex(encrypted);
content.removeAll();
......
Donc les compilateurs disent: Soit vous entourez cela avec une construction try/catch, soit vous déclarez la méthode (où est utilisée) pour se lancer "Exception" elle-même.
Le vrai problème est la définition de la méthode "encrypt". Aucune méthode ne devrait jamais retourner "Exception", car elle est trop générique et peut masquer d'autres types d'exceptions mieux vaut avoir une exception spécifique.
Essaye ça:
public static byte[] encrypt(String toEncrypt) {
try{
String plaintext = toEncrypt;
String key = "01234567890abcde";
String iv = "fedcba9876543210";
SecretKeySpec keyspec = new SecretKeySpec(key.getBytes(), "AES");
IvParameterSpec ivspec = new IvParameterSpec(iv.getBytes());
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE,keyspec,ivspec);
byte[] encrypted = cipher.doFinal(toEncrypt.getBytes());
return encrypted;
} catch ( NoSuchAlgorithmException nsae ) {
// What can you do if the algorithm doesn't exists??
// this usually won't happen because you would test
// your code before shipping.
// So in this case is ok to transform to another kind
throw new IllegalStateException( nsae );
} catch ( NoSuchPaddingException nspe ) {
// What can you do when there is no such padding ( whatever that means ) ??
// I guess not much, in either case you won't be able to encrypt the given string
throw new IllegalStateException( nsae );
}
// line 109 won't say it needs a return anymore.
}
Fondamentalement, dans ce cas particulier, vous devez vous assurer que le package de cryptographie est disponible dans le système.
Java a besoin d'une extension pour le paquet de cryptographie, donc les exceptions sont déclarées comme exceptions "vérifiées". A vous de les gérer lorsqu'ils ne sont pas présents.
Dans ce petit programme, vous ne pouvez rien faire si le package de cryptographie n'est pas disponible, vous devez donc vérifier cela au moment du "développement". Si ces exceptions sont levées lorsque votre programme est en cours d'exécution, c'est parce que vous avez fait quelque chose de mal dans le "développement", donc une sous-classe RuntimeException est plus appropriée.
La dernière ligne n'a plus besoin d'une instruction de retour, dans la première version, vous interceptiez l'exception et ne faites rien avec, c'est faux.
try {
// risky code ...
} catch( Exception e ) {
// a bomb has just exploited
// you should NOT ignore it
}
// The code continues here, but what should it do???
Si le code échoue, il vaut mieux échec rapide
Voici quelques réponses connexes:
La première erreur
Java.lang.Exception; doit être intercepté ou déclaré jeté octet [] encrypted = encrypt (concatURL);
signifie que votre méthode encrypt
lève une exception qui n'est pas gérée ou déclarée par la méthode actionPerformed
où vous l'appelez. Lisez tout à ce sujet dans le Java Exceptions Tutorial .
Vous avez deux choix parmi lesquels choisir pour obtenir le code à compiler.
throws Exception
à partir de votre méthode encrypt
et gère réellement l'exception à l'intérieur de encrypt
.encrypt
et ajouter throws Exception
et le bloc de gestion des exceptions à votre méthode actionPerformed
.Il est généralement préférable de gérer une exception au niveau le plus bas possible, au lieu de la passer à un niveau supérieur.
La deuxième erreur signifie simplement que vous devez ajouter une instruction de retour à la méthode qui contient la ligne 109 (également encrypt
, dans ce cas). Il y a une déclaration de retour dans la méthode, mais si une exception est levée, elle pourrait ne pas être atteinte, vous devez donc soit retourner dans le bloc catch, soit supprimer le try/catch de encrypt
, comme je l'ai mentionné précédemment .
Vous devrez décider comment vous souhaitez gérer les exceptions levées par la méthode encrypt
.
Actuellement, encrypt
est déclaré avec throws Exception
- cependant, dans le corps de la méthode, les exceptions sont interceptées dans un bloc try/catch. Je vous recommande soit:
throws Exception
clause de encrypt
et gérer les exceptions en interne (pensez au moins à écrire un message de log); ou,encrypt
, et entourez l'appel à encrypt
avec un try/catch à la place (ie dans actionPerformed
).En ce qui concerne l'erreur de compilation à laquelle vous faites référence: si une exception a été levée dans le bloc try
de encrypt
, rien n'est renvoyé après la fin du bloc catch
. Vous pouvez résoudre ce problème en déclarant initialement la valeur de retour comme null
:
public static byte[] encrypt(String toEncrypt) throws Exception{
byte[] encrypted = null;
try {
// ...
encrypted = ...
}
catch(Exception e){
// ...
}
return encrypted;
}
Cependant, si vous pouvez corriger le problème le plus important (la stratégie de gestion des exceptions), ce problème prendra soin de lui-même - en particulier si vous choisissez la deuxième option que j'ai suggérée.
Dans actionPerformed(ActionEvent e)
vous appelez encrypt()
, qui est déclaré pour lancer Exception
. Cependant, actionPerformed
ne capture pas cette exception (avec try/catch autour de l'appel à encrypt()
) ni ne déclare qu'elle jette Exception
elle-même.
Cependant, votre méthode encrypt
ne lance pas vraiment Exception
. Il avale toutes les exceptions sans même consigner une plainte. (Mauvaise pratique et mauvais style!)
De plus, votre méthode encrypt
effectue les opérations suivantes:
public static byte[] encrypt(String toEncrypt) throws Exception {
try{
....
return encrypted; // HERE YOU CORRECTLY RETURN A VALUE
} catch(Exception e) {
}
// YOU DO NOT RETURN ANYTHING HERE
}
C'est-à-dire que si vous interceptez une exception, vous la jetez en silence puis tombez du bas de votre méthode encrypt
sans réellement retourner quoi que ce soit. Cela ne se compilera pas (comme vous le voyez), car une méthode déclarée pour renvoyer une valeur doit soit renvoyer une valeur, soit lever une exception pour chaque chemin de code possible.
Dans votre méthode `` encrypt '', vous devez soit vous débarrasser du try/catch et ajouter à la place un try/catch à l'endroit où vous appelez encrypt (à l'intérieur de 'actionPerformed') ou renvoyer null à l'intérieur du catch dans encrypt (c'est la deuxième erreur.