hat*_*hat 6 java security encryption
我正在编写一个用于传输文件的小应用程序,或多或少是一种了解更多程序加密基础的方法.我们的想法是生成RSA密钥对,交换公钥,并发送AES iv和密钥以进行进一步解密.我想用接收器RSA公钥加密AES密钥,如下所示:
// encode the SecretKeySpec
private byte[] EncryptSecretKey ()
{
    Cipher cipher = null;
    byte[] key = null;
    try
    {
        cipher = Cipher.getInstance("RSA/ECB/NOPADDING");
        // contact.getPublicKey returns a public key of type Key
        cipher.init(Cipher.ENCRYPT_MODE, contact.getPublicKey() );
        // skey is the SecretKey used to encrypt the AES data
        key = cipher.doFinal(skey.getEncoded());
    }
    catch(Exception e )
    {
        System.out.println ( "exception encoding key: " + e.getMessage() );
        e.printStackTrace();
    }
    return key;
}
然后我将键值写入接收器,并像这样解密:
private SecretKey decryptAESKey(byte[] data )
{
    SecretKey key = null;
    PrivateKey privKey = null;
    Cipher cipher = null;
    System.out.println ( "Data as hex: " + utility.asHex(data) );
    System.out.println ( "data length: " + data.length );
    try
    {
        // assume this loads our private key
        privKey = (PrivateKey)utility.loadLocalKey("private.key", false);
        cipher = Cipher.getInstance("RSA/ECB/NOPADDING");
        cipher.init(Cipher.DECRYPT_MODE, privKey );
        key = new SecretKeySpec(cipher.doFinal(data), "AES");
        System.out.println ( "Key decrypted, length is " + key.getEncoded().length );
        System.out.println ( "data: " + utility.asHex(key.getEncoded()));
    }
    catch(Exception e)
    {
        System.out.println ( "exception decrypting the aes key: " + e.getMessage() );
        e.printStackTrace();
        return null;
    }
    return key;
}
在控制台中,另一方面,我将其作为输出:
read_bytes for key: 16
data length: 16
Data as hex: <hex string>
Key decrypted, length is 256
java.security.InvalidKeyException: Invalid AES key length: 256 bytes
此外,如果我创建一个大小为16的字节数组并将cipher.doFinal(data)输出放入其中,则该数组似乎被调整为256字节(.length表示至少如此).为什么会这样,而且,我做错了什么?
编辑
 
我解决了这个问题,并认为我会发布这个问题以防万一有人碰到这个问题.事实证明,问题是RSA/ECB/NOPADDING.出于某种奇怪的原因,当我将它转移到客户端时,它正在搞砸我创建的SecretKey.它可能与我如何生成密钥对有关(我正在使用getInstance("RSA")),但我不完全确定.
正如owlstead所提到的,你不能只使用"原始"RSA而不用填充加密/解密.一方面它非常不安全,另一方面,Java库甚至不支持它.以下是使用RSA密钥对加密/解密AES密钥的工作代码.
private byte[] EncryptSecretKey ()
{
    Cipher cipher = null;
    byte[] key = null;
    try
    {
        // initialize the cipher with the user's public key
        cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.ENCRYPT_MODE, contact.getPublicKey() );
        key = cipher.doFinal(skey.getEncoded());
    }
    catch(Exception e )
    {
        System.out.println ( "exception encoding key: " + e.getMessage() );
        e.printStackTrace();
    }
    return key;
}
AES密钥的解密如下所示:
private SecretKey decryptAESKey(byte[] data )
{
    SecretKey key = null;
    PrivateKey privKey = null;
    Cipher cipher = null;
    try
    {
        // this is OUR private key
        privKey = (PrivateKey)utility.loadLocalKey(
                                ConfigFrame.privateKeyLocation, false);
        // initialize the cipher...
        cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
        cipher.init(Cipher.DECRYPT_MODE, privKey );
        // generate the aes key!
        key = new SecretKeySpec ( cipher.doFinal(data), "AES" );
    }
    catch(Exception e)
    {
        System.out.println ( "exception decrypting the aes key: " 
                                               + e.getMessage() );
        return null;
    }
    return key;
}
| 归档时间: | 
 | 
| 查看次数: | 26519 次 | 
| 最近记录: |