Java throws 子句 - sonarqube 问题
Java throws clause - sonarqube issue
我有一些旧代码,我们 运行 sonarqube。我不是 Java 和 Exception 后代等方面的专家,所以我希望有人能够帮助我解决这个问题,因为 Sonar 说这是一个 blocker.
这是代码:
package xxx;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
public class Encryptor {
private static final String ALGORITHM = "AES";
private static final String defaultSecretKey = "xxx";
private Key secretKeySpec;
public Encryptor() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
UnsupportedEncodingException {
this(null);
}
public Encryptor(String secretKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
UnsupportedEncodingException {
this.secretKeySpec = generateKey(secretKey);
}
public String encrypt(String plainText) throws InvalidKeyException, NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
return asHexString(encrypted);
}
public String decrypt(String encryptedString) throws InvalidKeyException, IllegalBlockSizeException,
BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] original = cipher.doFinal(toByteArray(encryptedString));
return new String(original);
}
private Key generateKey(String secretKey) throws UnsupportedEncodingException, NoSuchAlgorithmException {
if (secretKey == null) {
secretKey = defaultSecretKey;
}
byte[] key = (secretKey).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-256");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only the first 128 bit
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(256); // 192 and 256 bits may not be available
return new SecretKeySpec(key, ALGORITHM);
}
private final String asHexString(byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10) {
strbuf.append("0");
}
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
private final byte[] toByteArray(String hexString) {
int arrLength = hexString.length() >> 1;
byte buf[] = new byte[arrLength];
for (int ii = 0; ii < arrLength; ii++) {
int index = ii << 1;
String l_digit = hexString.substring(index, index + 2);
buf[ii] = (byte) Integer.parseInt(l_digit, 16);
}
return buf;
}
public static void main(String[] args) throws Exception {
if (args.length == 1) {
String plainText = args[0];
Encryptor aes = new Encryptor();
String encryptedString = aes.encrypt(plainText);
//this line only ensures that decryption works
String decryptedString = aes.decrypt(encryptedString);
System.out.println("Original Password: " + plainText + " and Encrypted Password: " + encryptedString);
} else {
System.out.println("USAGE: java AES string-to-encrypt");
}
}
}
问题出在这一行:
public static void main(String[] args) throws Exception {
Sonar 说 删除这个 throws 子句
有人知道如何解决这个问题或为什么会这样吗?
非常感谢。
男.
感谢所有评论:
这是解决方案(删除通用异常并添加显式异常):
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
使用最小公分母始终是一个好方法,或者更具体地说,异常 class 为其所有后代提供最佳抽象。
考虑以下方法声明:
public String encrypt(String plainText)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException,
UnsupportedEncodingException {
// body
}
仔细检查所有这些异常会发现它们都扩展了 GeneralSecurityException
。因此,可以将上述代码重构为:
public String encrypt(String plainText) throws GeneralSecurityException,
UnsupportedEncodingException {
// body
}
唯一不继承 GeneralSecurityException
的例外是 UnsupportedEncodingException
,因此您必须显式声明它。
从客户端考虑:您更愿意使用哪个版本?
try {
String encrypted = cipher.encrypt("Test");
} catch(InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
| UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException e) {
// cannot encrypt
} catch(UnsupportedEncodingException e) {
// wrong encoding
}
try {
String encrypted = cipher.encrypt("Test");
} catch(GeneralSecurityException e) {
// cannot encrypt
} catch(UnsupportedEncodingException e) {
// wrong encoding
}
我有一些旧代码,我们 运行 sonarqube。我不是 Java 和 Exception 后代等方面的专家,所以我希望有人能够帮助我解决这个问题,因为 Sonar 说这是一个 blocker.
这是代码:
package xxx;
import java.io.UnsupportedEncodingException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
public class Encryptor {
private static final String ALGORITHM = "AES";
private static final String defaultSecretKey = "xxx";
private Key secretKeySpec;
public Encryptor() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
UnsupportedEncodingException {
this(null);
}
public Encryptor(String secretKey) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException,
UnsupportedEncodingException {
this.secretKeySpec = generateKey(secretKey);
}
public String encrypt(String plainText) throws InvalidKeyException, NoSuchAlgorithmException,
NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
return asHexString(encrypted);
}
public String decrypt(String encryptedString) throws InvalidKeyException, IllegalBlockSizeException,
BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
Cipher cipher = Cipher.getInstance(ALGORITHM);
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
byte[] original = cipher.doFinal(toByteArray(encryptedString));
return new String(original);
}
private Key generateKey(String secretKey) throws UnsupportedEncodingException, NoSuchAlgorithmException {
if (secretKey == null) {
secretKey = defaultSecretKey;
}
byte[] key = (secretKey).getBytes("UTF-8");
MessageDigest sha = MessageDigest.getInstance("SHA-256");
key = sha.digest(key);
key = Arrays.copyOf(key, 16); // use only the first 128 bit
KeyGenerator kgen = KeyGenerator.getInstance("AES");
kgen.init(256); // 192 and 256 bits may not be available
return new SecretKeySpec(key, ALGORITHM);
}
private final String asHexString(byte buf[]) {
StringBuffer strbuf = new StringBuffer(buf.length * 2);
int i;
for (i = 0; i < buf.length; i++) {
if (((int) buf[i] & 0xff) < 0x10) {
strbuf.append("0");
}
strbuf.append(Long.toString((int) buf[i] & 0xff, 16));
}
return strbuf.toString();
}
private final byte[] toByteArray(String hexString) {
int arrLength = hexString.length() >> 1;
byte buf[] = new byte[arrLength];
for (int ii = 0; ii < arrLength; ii++) {
int index = ii << 1;
String l_digit = hexString.substring(index, index + 2);
buf[ii] = (byte) Integer.parseInt(l_digit, 16);
}
return buf;
}
public static void main(String[] args) throws Exception {
if (args.length == 1) {
String plainText = args[0];
Encryptor aes = new Encryptor();
String encryptedString = aes.encrypt(plainText);
//this line only ensures that decryption works
String decryptedString = aes.decrypt(encryptedString);
System.out.println("Original Password: " + plainText + " and Encrypted Password: " + encryptedString);
} else {
System.out.println("USAGE: java AES string-to-encrypt");
}
}
}
问题出在这一行:
public static void main(String[] args) throws Exception {
Sonar 说 删除这个 throws 子句
有人知道如何解决这个问题或为什么会这样吗?
非常感谢。
男.
感谢所有评论:
这是解决方案(删除通用异常并添加显式异常):
public static void main(String[] args) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException {
使用最小公分母始终是一个好方法,或者更具体地说,异常 class 为其所有后代提供最佳抽象。
考虑以下方法声明:
public String encrypt(String plainText)
throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException,
UnsupportedEncodingException, IllegalBlockSizeException, BadPaddingException,
UnsupportedEncodingException {
// body
}
仔细检查所有这些异常会发现它们都扩展了 GeneralSecurityException
。因此,可以将上述代码重构为:
public String encrypt(String plainText) throws GeneralSecurityException,
UnsupportedEncodingException {
// body
}
唯一不继承 GeneralSecurityException
的例外是 UnsupportedEncodingException
,因此您必须显式声明它。
从客户端考虑:您更愿意使用哪个版本?
try {
String encrypted = cipher.encrypt("Test");
} catch(InvalidKeyException | NoSuchAlgorithmException | NoSuchPaddingException
| UnsupportedEncodingException | IllegalBlockSizeException | BadPaddingException e) {
// cannot encrypt
} catch(UnsupportedEncodingException e) {
// wrong encoding
}
try {
String encrypted = cipher.encrypt("Test");
} catch(GeneralSecurityException e) {
// cannot encrypt
} catch(UnsupportedEncodingException e) {
// wrong encoding
}