Java - 使用 AES/CBC/NoPadding 时出现 InvalidKeyException

Java - InvalidKeyException when using AES/CBC/NoPadding

当我将 Cipher.getInstance("AES") 切换为 Cipher.getInstance("AES/CBC/NoPadding") 时,我开始收到此错误:

    12:18:20 [SEVERE] java.security.InvalidKeyException: No installed provider supports this key: javax.crypto.spec.SecretKeySpec
    12:18:20 [SEVERE]     at javax.crypto.Cipher.chooseProvider(Cipher.java:878)
    12:18:20 [SEVERE]     at javax.crypto.Cipher.init(Cipher.java:1213)
    12:18:20 [SEVERE]     at javax.crypto.Cipher.init(Cipher.java:1153)
    12:18:20 [SEVERE]     at net.azidea.bungee.netty.packet.codec.Encryption.decrypt(Encryption.java:52)
    12:18:20 [SEVERE]     at net.azidea.bungee.netty.packet.codec.PacketDecrypter.decode(PacketDecrypter.java:20)
    12:18:20 [SEVERE]     at net.azidea.bungee.netty.packet.codec.PacketDecrypter.decode(PacketDecrypter.java:12)
    12:18:20 [SEVERE]     at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:89)
    12:18:20 [SEVERE]     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    12:18:20 [SEVERE]     at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    12:18:20 [SEVERE]     at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:161)
    12:18:20 [SEVERE]     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    12:18:20 [SEVERE]     at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    12:18:20 [SEVERE]     at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:86)
    12:18:20 [SEVERE]     at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:333)
    12:18:20 [SEVERE]     at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:319)
    12:18:20 [SEVERE]     at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:787)
    12:18:20 [SEVERE]     at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:130)
    12:18:20 [SEVERE]     at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:511)
    12:18:20 [SEVERE]     at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:468)
    12:18:20 [SEVERE]     at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:382)
    12:18:20 [SEVERE]     at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:354)
    12:18:20 [SEVERE]     at io.netty.util.concurrent.SingleThreadEventExecutor.run(SingleThreadEventExecutor.java:116)
    12:18:20 [SEVERE]     at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
    12:18:20 [SEVERE]     at java.lang.Thread.run(Thread.java:745)

解密时。它仅使用 AES(没有 "CBC/NoPadding" 部分)就可以正常工作。我更改了这个,因为并非我所有的数据包都是 16 字节的倍数。

key.getAlgorithm()的输出是"AES"。

Decryption

public static ByteBuf decrypt(ByteBuf encrypted)
{
    try
    {
        cipher.init(Cipher.DECRYPT_MODE, key);
        return Unpooled.copiedBuffer(cipher.doFinal(NettyUtils.toArray(encrypted)));
    }
    catch(Exception e)
    {
        e.printStackTrace();
        System.out.println("[Netty] Error decrypting packet.");
    }

    return null;
}

Cipher

private static Cipher cipher;
private static SecretKeySpec key;

static
{
    try
    {
        key = new SecretKeySpec(NettyServer.getSecretKey(), "AES");
        cipher = Cipher.getInstance("AES/CBC/NoPadding");
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
}

指定 IvParameterSpec 解决了问题。