栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

AES加密IV

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

AES加密IV

AES密钥仅由随机字节组成。对于CBC模式,IV模式也应该是随机的(至少对攻击者而言)。因此,通常您可以简单地使用

SecureRandom
实例来创建密钥和IV。IV可以包含在密文中。通常它只是放在它的前面。

对于Java,最好使用

KeyGenerator
尽管。如果您在SUN提供程序中查看它的实现,则可能等同于同一件事。但是,使用a
KeyGenerator
与各种密钥和提供程序更兼容。很有可能是在例如智能卡和HSM中生成密钥的要求。

因此,让我们用三个简单的方法显示一个类:

package nl.owlstead.stackoverflow;import static java.nio.charset.StandardCharsets.UTF_8;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import java.security.NoSuchAlgorithmException;import java.security.Provider;import java.security.SecureRandom;import java.util.Optional;import javax.crypto.Cipher;import javax.crypto.CipherInputStream;import javax.crypto.CipherOutputStream;import javax.crypto.KeyGenerator;import javax.crypto.SecretKey;import javax.crypto.spec.IvParameterSpec;public class CreateKeyAndIVForAES_CBC {    public static SecretKey createKey(final String algorithm, final int keysize, final Optional<Provider> provider, final Optional<SecureRandom> rng) throws NoSuchAlgorithmException {        final KeyGenerator keyGenerator;        if (provider.isPresent()) { keyGenerator = KeyGenerator.getInstance(algorithm, provider.get());        } else { keyGenerator = KeyGenerator.getInstance(algorithm);        }        if (rng.isPresent()) { keyGenerator.init(keysize, rng.get());        } else { // not really needed for the Sun provider which handles null OK keyGenerator.init(keysize);        }        return keyGenerator.generateKey();    }    public static IvParameterSpec createIV(final int ivSizeBytes, final Optional<SecureRandom> rng) {        final byte[] iv = new byte[ivSizeBytes];        final SecureRandom theRNG = rng.orElse(new SecureRandom());        theRNG.nextBytes(iv);        return new IvParameterSpec(iv);    }    public static IvParameterSpec readIV(final int ivSizeBytes, final InputStream is) throws IOException {        final byte[] iv = new byte[ivSizeBytes];        int offset = 0;        while (offset < ivSizeBytes) { final int read = is.read(iv, offset, ivSizeBytes - offset); if (read == -1) {     throw new IOException("Too few bytes for IV in input stream"); } offset += read;        }        return new IvParameterSpec(iv);    }    public static void main(String[] args) throws Exception {        final SecureRandom rng = new SecureRandom();        // you somehow need to distribute this key        final SecretKey aesKey = createKey("AES", 128, Optional.empty(), Optional.of(rng));        final byte[] plaintext = "owlstead".getBytes(UTF_8);        final byte[] ciphertext;        { final ByteArrayOutputStream baos = new ByteArrayOutputStream(); final Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding"); final IvParameterSpec ivForCBC = createIV(aesCBC.getBlockSize(), Optional.of(rng)); aesCBC.init(Cipher.ENCRYPT_MODE, aesKey, ivForCBC); baos.write(ivForCBC.getIV()); try (final CipherOutputStream cos = new CipherOutputStream(baos, aesCBC)) {     cos.write(plaintext); } ciphertext = baos.toByteArray();        }        final byte[] decrypted;        { final ByteArrayInputStream bais = new ByteArrayInputStream(ciphertext); final Cipher aesCBC = Cipher.getInstance("AES/CBC/PKCS5Padding"); final IvParameterSpec ivForCBC = readIV(aesCBC.getBlockSize(), bais); aesCBC.init(Cipher.DECRYPT_MODE, aesKey, ivForCBC); final byte[] buf = new byte[1_024]; try (final CipherInputStream cis = new CipherInputStream(bais, aesCBC);         final ByteArrayOutputStream baos = new ByteArrayOutputStream()) {     int read;     while ((read = cis.read(buf)) != -1) {         baos.write(buf, 0, read);     }     decrypted = baos.toByteArray(); }        }        System.out.println(new String(decrypted, UTF_8));    }}

请注意,您可能并不总是希望“带外”生成和分发AES密钥。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/451520.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号