001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 */ 019package org.apache.shiro.crypto.cipher; 020 021import javax.crypto.spec.GCMParameterSpec; 022import java.security.spec.AlgorithmParameterSpec; 023 024/** 025 * {@code CipherService} using the {@code AES} cipher algorithm for all encryption, decryption, and key operations. 026 * <p/> 027 * The AES algorithm can support key sizes of {@code 128}, {@code 192} and {@code 256} bits<b>*</b>. This implementation 028 * defaults to 128 bits. 029 * <p/> 030 * Note that this class retains changes the parent class's default 031 * {@link OperationMode#CBC CBC} modeto {@link OperationMode#GCM GCM} of operation 032 * instead of the typical JDK default of {@link OperationMode#ECB ECB}. 033 * {@code ECB} should not be used in security-sensitive environments because {@code ECB} 034 * does not allow for initialization vectors, which are considered necessary for strong encryption. 035 * See the {@link DefaultBlockCipherService parent class}'s JavaDoc and the 036 * {@link JcaCipherService JcaCipherService} JavaDoc for more on why the JDK default should not be used and is not 037 * used in this implementation. 038 * <p/> 039 * <b>*</b> Generating and using AES key sizes greater than 128 require installation of the 040 * <a href="http://java.sun.com/javase/downloads/index.jsp">Java Cryptography Extension (JCE) Unlimited Strength 041 * Jurisdiction Policy files</a>. 042 * 043 * @since 1.0 044 */ 045public class AesCipherService extends DefaultBlockCipherService { 046 047 private static final String ALGORITHM_NAME = "AES"; 048 049 /** 050 * Creates a new {@link CipherService} instance using the {@code AES} cipher algorithm with the following 051 * important cipher default attributes: 052 * <table> 053 * <tr> 054 * <th>Attribute</th> 055 * <th>Value</th> 056 * </tr> 057 * <tr> 058 * <td>{@link #setKeySize keySize}</td> 059 * <td>{@code 128} bits</td> 060 * </tr> 061 * <tr> 062 * <td>{@link #setBlockSize blockSize}</td> 063 * <td>{@code 128} bits (required for {@code AES}</td> 064 * </tr> 065 * <tr> 066 * <td>{@link #setMode mode}</td> 067 * <td>{@link OperationMode#GCM GCM}<b>*</b></td> 068 * </tr> 069 * <tr> 070 * <td>{@link #setPaddingScheme paddingScheme}</td> 071 * <td>{@link PaddingScheme#NONE NoPadding}***</td> 072 * </tr> 073 * <tr> 074 * <td>{@link #setInitializationVectorSize(int) initializationVectorSize}</td> 075 * <td>{@code 128} bits</td> 076 * </tr> 077 * <tr> 078 * <td>{@link #setGenerateInitializationVectors(boolean) generateInitializationVectors}</td> 079 * <td>{@code true}<b>**</b></td> 080 * </tr> 081 * </table> 082 * <p/> 083 * <b>*</b> The {@link OperationMode#GCM GCM} operation mode is used instead of the JDK default {@code ECB} to 084 * ensure strong encryption. {@code ECB} should not be used in security-sensitive environments - see the 085 * {@link DefaultBlockCipherService DefaultBlockCipherService} class JavaDoc's "Operation Mode" section 086 * for more. 087 * <p/> 088 * <b>**</b>In conjunction with the default {@code GCM} operation mode, initialization vectors are generated by 089 * default to ensure strong encryption. See the {@link JcaCipherService JcaCipherService} class JavaDoc for more. 090 * <p/> 091 * <b>**</b>Since {@code GCM} is a stream cipher, padding is implemented in the operation mode and an external padding scheme 092 * cannot be used in conjunction with {@code GCM}. In fact, {@code AES/GCM/PKCS5Padding} is just an alias in most JVM for 093 * {@code AES/GCM/NoPadding}. 094 * <p/> 095 * <b>NOTE:</b> As of Java 14, setting a streaming padding for the above example will throw a NoSuchAlgorithmException 096 * 097 * @see <a href="https://www.oracle.com/java/technologies/javase/14-relnote-issues.html#JDK-8180392">JDK-8180392</a> 098 */ 099 public AesCipherService() { 100 super(ALGORITHM_NAME); 101 setMode(OperationMode.GCM); 102 setStreamingMode(OperationMode.GCM); 103 setPaddingScheme(PaddingScheme.NONE); 104 setStreamingPaddingScheme(PaddingScheme.NONE); 105 } 106 107 @Override 108 protected AlgorithmParameterSpec createParameterSpec(byte[] iv, boolean streaming) { 109 110 if ((streaming && OperationMode.GCM.name().equals(getStreamingModeName())) 111 || (!streaming && OperationMode.GCM.name().equals(getModeName()))) { 112 return new GCMParameterSpec(getKeySize(), iv); 113 } 114 115 return super.createParameterSpec(iv, streaming); 116 } 117}