首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用javax.crypto的AES和RSA

使用javax.crypto的AES和RSA
EN

Code Review用户
提问于 2016-03-16 04:25:47
回答 2查看 3.6K关注 0票数 4

所以我假设我做错了什么,我的AES和RSA加密和解密类是不安全的。我计划在一个更大的项目中使用它们,并希望确保我没有首先完全屏蔽它们。我的问题如下:

  1. 如果有的话,是什么使这两个类不安全呢?
  2. 如果有的话,我的代码会变得更整洁/更好吗?
  3. 我有什么不想问的

AES:

代码语言:javascript
复制
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

/**
 * Created by Gabriel Wittes on 3/15/2016.
 * A class to encrypt and decrypt AES plaintext and ciphertext, as well as to generate AES keys.
 */
public class AES {
    /**
     * Returns a new secret AES key.
     * @return a secret AES key
     */
    public static SecretKey generateKey(){
        KeyGenerator keyGenerator = null;
        try {
            keyGenerator = KeyGenerator.getInstance("AES");
            keyGenerator.init(128);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return keyGenerator.generateKey();
    }

    /**
     * Returns an AES-encrypted byte array given a plaintext string and a secret AES key.
     * @param plaintext a plaintext string
     * @param key a secret AES key
     * @return ciphertext
     */
    public static byte[] encrypt(String plaintext, SecretKey key){
        byte[] ciphertext = null;
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            ciphertext = cipher.doFinal(plaintext.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ciphertext;
    }

    /**
     * Returns the plaintext of a given AES-encrypted string, and a secret AES key.
     * @param ciphertext an AES encrypted byte array
     * @param key a secret AES key
     * @return plaintext
     */
    public static String decrypt(byte[] ciphertext, SecretKey key){
        byte[] plaintext = null;
        try {
            Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
            cipher.init(Cipher.DECRYPT_MODE, key);
            plaintext = cipher.doFinal(ciphertext);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new String(plaintext);
    }
}

RSA:

代码语言:javascript
复制
import javax.crypto.Cipher;
import java.security.*;

/**
 * Created by Gabriel Wittes on 3/15/2016.
 * A class to encrypt and decrypt RSA plaintext and ciphertext, as well as to generate RSA key pairs.
 */
public class RSA {
    /**
     * Returns a new RSA key pair.
     * @return public and private RSA keys
     */
    public static KeyPair generateKeyPair(){
        KeyPairGenerator keyPairGenerator = null;
        try {
            keyPairGenerator = KeyPairGenerator.getInstance("RSA");
            keyPairGenerator.initialize(2048);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return keyPairGenerator.generateKeyPair();
    }

    /**
     * Returns an RSA-encrypted byte array given a plaintext string and a public RSA key.
     * @param plaintext a plaintext string
     * @param key a public RSA key
     * @return ciphertext
     */
    public static byte[] encrypt(String plaintext, PublicKey key){
        byte[] ciphertext = null;
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/OASP");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            ciphertext = cipher.doFinal(plaintext.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return ciphertext;
    }

    /**
     * Returns the plaintext of a given RSA-encrypted string and a private RSA key.
     * @param ciphertext an RSA-encrypted byte array
     * @param key a private RSA key
     * @return plaintext
     */
    public static String decrypt(byte[] ciphertext, PrivateKey key){
        byte[] plaintext = null;
        try {
            Cipher cipher = Cipher.getInstance("RSA/ECB/OASP");
            cipher.init(Cipher.DECRYPT_MODE, key);
            plaintext = cipher.doFinal(ciphertext);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new String(plaintext);
    }
}
EN

回答 2

Code Review用户

回答已采纳

发布于 2016-03-16 14:44:06

三项评论:

首先,不要抓住这样的例外,特别是不是所有的例外。理想情况下,您希望尽早收到有关错误的通知,而不是在下一个调用失败时通知您,所以我不认为有好的理由将catch放在那里。如果您确实希望将异常转换为另一个返回值(或异常),则使其更加显式。还有。printStackTrace不能很好地使用日志框架,所以也是如此。

第二,为什么所有的方法都是静态的?这将(很容易)允许您模拟这个类,这是一个很好的东西,当测试(您有测试,对吗?)

第三,字符串构造函数应该有一个显式的字符集参数,或者至少您应该确保默认平台编码是您所期望的(当然,UTF-8)。字符串常量也应该声明为private static final String ALGORITHM = ...左右。

票数 3
EN

Code Review用户

发布于 2016-03-16 11:32:18

你的课程在我看来是安全的,我唯一的建议是

  1. 使您的方法更通用:我将使用byte[]类型的参数和返回类型公共类AES {.公开静态byte[]加密( byte[]平原,SecretKey密钥){.}公共静态byte[]解密(byte[]加密,SecretKey密钥){.}公共类RSA {.公共静态byte[]加密( byte[]平原,PublicKey密钥){.}公共静态byte[]解密(byte[] encrypted,PrivateKey key) {.}}这可能不仅有字符串要加密/解密,而且应该始终加密/解密调用AES.decrypt(string.getBytes(), key);的字符串
  2. RSA类中添加PrivateKey加密和PublicKey解密的方法:公钥RSA {.公共静态byte[]加密( byte[]平原,PublicKey密钥){.}公共静态byte[]解密( byte[]加密,PrivateKey密钥){.}公共静态byte[]加密(byte[]平原,PrivateKey密钥){.}公开静态byte[]解密(byte[]加密,( PublicKey密钥){.}这是因为RSA可以两种方式工作,例如在数字签名中,发送方用他的私钥加密消息的消化,因此接收方可以用发送方的公钥解密摘要,以验证消息的完整性和真实性。
票数 2
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/122971

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档