001/** 002 * Copyright 2010-2014 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.common.util.encrypt.openssl; 017 018import static org.kuali.common.util.base.Precondition.checkMin; 019import static org.kuali.common.util.base.Precondition.checkNotBlank; 020import static org.kuali.common.util.encrypt.EncryptionStrength.STRONG_ENCRYPTION_STRENGTH; 021 022import org.kuali.common.util.encrypt.EncryptionStrength; 023 024public final class OpenSSLContext { 025 026 private final int iterations; 027 private final String saltPrefix; 028 private final int saltSize; 029 private final int keySizeBits; 030 private final String transformation; 031 private final String digestAlgorithm; 032 private final String algorithm; 033 034 private OpenSSLContext(Builder builder) { 035 this.iterations = builder.iterations; 036 this.saltSize = builder.saltSize; 037 this.saltPrefix = builder.saltPrefix; 038 this.keySizeBits = builder.keySizeBits; 039 this.transformation = builder.transformation; 040 this.digestAlgorithm = builder.digestAlgorithm; 041 this.algorithm = builder.algorithm; 042 } 043 044 /** 045 * <p> 046 * <code>EncryptionStrength.STRONG_ENCRYPTION_STRENGTH</code> means AES 256, otherwise AES 128. 047 * <p> 048 * 049 * <p> 050 * <strong>WARNING:</strong> AES 256 causes an exception to be thrown unless you've installed java's "unlimited strength jurisdiction policy files" 051 * </p> 052 */ 053 public static OpenSSLContext buildOpenSSLContext(EncryptionStrength strength) { 054 if (STRONG_ENCRYPTION_STRENGTH.equals(strength)) { 055 return builder().withKeySizeBits(Builder.STRONG_KEY_SIZE_BITS).build(); 056 } else { 057 return buildDefaultOpenSSLContext(); 058 } 059 } 060 061 /** 062 * Returns a context for 128 bit AES encryption compatible with OpenSSL 063 */ 064 public static OpenSSLContext buildDefaultOpenSSLContext() { 065 return builder().build(); 066 } 067 068 public static Builder builder() { 069 return new Builder(); 070 } 071 072 public static class Builder implements org.apache.commons.lang3.builder.Builder<OpenSSLContext> { 073 074 private static final int STRONG_KEY_SIZE_BITS = 256; 075 076 private int iterations = 1; 077 private String saltPrefix = "Salted__"; 078 private int saltSize = 8; 079 private int keySizeBits = 128; 080 private String transformation = "AES/CBC/PKCS5Padding"; 081 private String digestAlgorithm = "MD5"; 082 private String algorithm = "AES"; 083 084 private static OpenSSLContext validate(OpenSSLContext instance) { 085 checkMin(instance.iterations, 0, "iterations"); 086 checkNotBlank(instance.saltPrefix, "saltPrefix"); 087 checkMin(instance.saltSize, 0, "saltSize"); 088 checkMin(instance.keySizeBits, 0, "keySizeBits"); 089 checkNotBlank(instance.transformation, "transformation"); 090 checkNotBlank(instance.digestAlgorithm, "digest"); 091 checkNotBlank(instance.algorithm, "algorithm"); 092 return instance; 093 } 094 095 @Override 096 public OpenSSLContext build() { 097 return validate(new OpenSSLContext(this)); 098 } 099 100 public Builder withAlgorithm(String algorithm) { 101 this.algorithm = algorithm; 102 return this; 103 } 104 105 public Builder withSaltPrefix(String saltPrefix) { 106 this.saltPrefix = saltPrefix; 107 return this; 108 } 109 110 public Builder withDigestAlgorithm(String digestAlgorithm) { 111 this.digestAlgorithm = digestAlgorithm; 112 return this; 113 } 114 115 public Builder withTransformation(String transformation) { 116 this.transformation = transformation; 117 return this; 118 } 119 120 public Builder withIterations(int iterations) { 121 this.iterations = iterations; 122 return this; 123 } 124 125 public Builder withSaltSize(int saltSize) { 126 this.saltSize = saltSize; 127 return this; 128 } 129 130 public Builder withKeySizeBits(int keySizeBits) { 131 this.keySizeBits = keySizeBits; 132 return this; 133 } 134 135 public int getIterations() { 136 return iterations; 137 } 138 139 public void setIterations(int iterations) { 140 this.iterations = iterations; 141 } 142 143 public String getSaltPrefix() { 144 return saltPrefix; 145 } 146 147 public void setSaltPrefix(String saltPrefix) { 148 this.saltPrefix = saltPrefix; 149 } 150 151 public int getSaltSize() { 152 return saltSize; 153 } 154 155 public void setSaltSize(int saltSize) { 156 this.saltSize = saltSize; 157 } 158 159 public int getKeySizeBits() { 160 return keySizeBits; 161 } 162 163 public void setKeySizeBits(int keySizeBits) { 164 this.keySizeBits = keySizeBits; 165 } 166 167 public String getTransformation() { 168 return transformation; 169 } 170 171 public void setTransformation(String transformation) { 172 this.transformation = transformation; 173 } 174 175 public String getDigestAlgorithm() { 176 return digestAlgorithm; 177 } 178 179 public void setDigestAlgorithm(String digest) { 180 this.digestAlgorithm = digest; 181 } 182 183 public String getAlgorithm() { 184 return algorithm; 185 } 186 187 public void setAlgorithm(String algorithm) { 188 this.algorithm = algorithm; 189 } 190 } 191 192 public int getIterations() { 193 return iterations; 194 } 195 196 public int getSaltSize() { 197 return saltSize; 198 } 199 200 public int getKeySizeBits() { 201 return keySizeBits; 202 } 203 204 public String getTransformation() { 205 return transformation; 206 } 207 208 public String getDigestAlgorithm() { 209 return digestAlgorithm; 210 } 211 212 public String getAlgorithm() { 213 return algorithm; 214 } 215 216 public String getSaltPrefix() { 217 return saltPrefix; 218 } 219}