1 // Copyright 2017 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 // 15 //////////////////////////////////////////////////////////////////////////////// 16 17 package com.google.crypto.tink.signature; 18 19 import com.google.crypto.tink.proto.EcdsaKeyFormat; 20 import com.google.crypto.tink.proto.EcdsaParams; 21 import com.google.crypto.tink.proto.EcdsaSignatureEncoding; 22 import com.google.crypto.tink.proto.EllipticCurveType; 23 import com.google.crypto.tink.proto.HashType; 24 import com.google.crypto.tink.proto.KeyTemplate; 25 import com.google.crypto.tink.proto.OutputPrefixType; 26 import com.google.crypto.tink.proto.RsaSsaPkcs1KeyFormat; 27 import com.google.crypto.tink.proto.RsaSsaPkcs1Params; 28 import com.google.crypto.tink.proto.RsaSsaPssKeyFormat; 29 import com.google.crypto.tink.proto.RsaSsaPssParams; 30 import com.google.protobuf.ByteString; 31 import java.math.BigInteger; 32 import java.security.spec.RSAKeyGenParameterSpec; 33 34 /** 35 * Pre-generated {@link KeyTemplate} for {@link com.google.crypto.tink.PublicKeySign} and {@link 36 * com.google.crypto.tink.PublicKeyVerify}. 37 * 38 * <p>We recommend to avoid this class in order to keep dependencies small. 39 * 40 * <ul> 41 * <li>Using this class adds a dependency on protobuf. We hope that eventually it is possible to 42 * use Tink without a dependency on protobuf. 43 * <li>Using this class adds a dependency on classes for all involved key types. 44 * </ul> 45 * 46 * These dependencies all come from static class member variables, which are initialized when the 47 * class is loaded. This implies that static analysis and code minimization tools (such as proguard) 48 * cannot remove the usages either. 49 * 50 * <p>Instead, we recommend to use {@code KeysetHandle.generateEntryFromParametersName} or {@code 51 * KeysetHandle.generateEntryFromParameters}. 52 * 53 * <p>One can use these templates to generate new {@link com.google.crypto.tink.proto.Keyset} with 54 * {@link com.google.crypto.tink.KeysetHandle}. To generate a new keyset that contains a single 55 * {@code EcdsaPrivateKey}, one can do: 56 * 57 * <pre>{@code 58 * SignatureConfig.register(); 59 * KeysetHandle handle = KeysetHandle.generateNew(SignatureKeyTemplates.ECDSA_P256); 60 * PublicKeySign signer = handle.getPrimitive(RegistryConfiguration.get(), PublicKeySign.class); 61 * PublicKeyVerify verifier = 62 * handle.getPublicKeyset().getPrimitive(RegistryConfiguration.get(), PublicKeyVerify.class); 63 * }</pre> 64 * 65 * @since 1.0.0 66 */ 67 public final class SignatureKeyTemplates { 68 /** 69 * A {@link KeyTemplate} that generates new instances of {@link 70 * com.google.crypto.tink.proto.EcdsaPrivateKey} with the following parameters: 71 * 72 * <ul> 73 * <li>Hash function: SHA256 74 * <li>Curve: NIST P-256 75 * <li>Signature encoding: DER (this is the encoding that Java uses). 76 * <li>Prefix type: {@link OutputPrefixType.TINK} 77 * </ul> 78 */ 79 public static final KeyTemplate ECDSA_P256 = 80 createEcdsaKeyTemplate( 81 HashType.SHA256, 82 EllipticCurveType.NIST_P256, 83 EcdsaSignatureEncoding.DER, 84 OutputPrefixType.TINK); 85 86 /** 87 * A {@link KeyTemplate} that generates new instances of {@link 88 * com.google.crypto.tink.proto.EcdsaPrivateKey} with the following parameters: 89 * 90 * <ul> 91 * <li>Hash function: SHA512 92 * <li>Curve: NIST P-384 93 * <li>Signature encoding: DER (this is the encoding that Java uses). 94 * <li>Prefix type: {@link OutputPrefixType.TINK} 95 * </ul> 96 */ 97 public static final KeyTemplate ECDSA_P384 = 98 createEcdsaKeyTemplate( 99 HashType.SHA512, 100 EllipticCurveType.NIST_P384, 101 EcdsaSignatureEncoding.DER, 102 OutputPrefixType.TINK); 103 104 /** 105 * A {@link KeyTemplate} that generates new instances of {@link 106 * com.google.crypto.tink.proto.EcdsaPrivateKey} with the following parameters: 107 * 108 * <ul> 109 * <li>Hash function: SHA512 110 * <li>Curve: NIST P-521 111 * <li>Signature encoding: DER (this is the encoding that Java uses). 112 * <li>Prefix type: {@link OutputPrefixType.TINK} 113 * </ul> 114 */ 115 public static final KeyTemplate ECDSA_P521 = 116 createEcdsaKeyTemplate( 117 HashType.SHA512, 118 EllipticCurveType.NIST_P521, 119 EcdsaSignatureEncoding.DER, 120 OutputPrefixType.TINK); 121 122 /** 123 * A {@link KeyTemplate} that generates new instances of {@link 124 * com.google.crypto.tink.proto.EcdsaPrivateKey} with the following parameters: 125 * 126 * <ul> 127 * <li>Hash function: SHA256 128 * <li>Curve: NIST P-256 129 * <li>Signature encoding: IEEE_P1363 (this is the encoding that JWS and WebCrypto use). 130 * <li>Prefix type: {@link OutputPrefixType.TINK} 131 * </ul> 132 */ 133 public static final KeyTemplate ECDSA_P256_IEEE_P1363 = 134 createEcdsaKeyTemplate( 135 HashType.SHA256, 136 EllipticCurveType.NIST_P256, 137 EcdsaSignatureEncoding.IEEE_P1363, 138 OutputPrefixType.TINK); 139 140 /** 141 * A {@link KeyTemplate} that generates new instances of {@link 142 * com.google.crypto.tink.proto.EcdsaPrivateKey} with the following parameters: 143 * 144 * <ul> 145 * <li>Hash function: SHA512 146 * <li>Curve: NIST P-384 147 * <li>Signature encoding: IEEE_P1363 (this is the encoding that JWS and WebCrypto use). 148 * <li>Prefix type: {@link OutputPrefixType.TINK} 149 * </ul> 150 */ 151 public static final KeyTemplate ECDSA_P384_IEEE_P1363 = 152 createEcdsaKeyTemplate( 153 HashType.SHA512, 154 EllipticCurveType.NIST_P384, 155 EcdsaSignatureEncoding.IEEE_P1363, 156 OutputPrefixType.TINK); 157 158 /** 159 * A {@link KeyTemplate} that generates new instances of {@link 160 * com.google.crypto.tink.proto.EcdsaPrivateKey} with the following parameters: 161 * 162 * <ul> 163 * <li>Hash function: SHA256 164 * <li>Curve: NIST P-256 165 * <li>Signature encoding: DER (this is the encoding that Java uses). 166 * <li>Prefix type: None 167 * </ul> 168 * 169 * The digital signature generated by this key would be 64 bytes exactly. 170 */ 171 public static final KeyTemplate ECDSA_P256_IEEE_P1363_WITHOUT_PREFIX = 172 createEcdsaKeyTemplate( 173 HashType.SHA256, 174 EllipticCurveType.NIST_P256, 175 EcdsaSignatureEncoding.IEEE_P1363, 176 OutputPrefixType.RAW); 177 178 /** 179 * A {@link KeyTemplate} that generates new instances of {@link 180 * com.google.crypto.tink.proto.EcdsaPrivateKey} with the following parameters: 181 * 182 * <ul> 183 * <li>Hash function: SHA512 184 * <li>Curve: NIST P-521 185 * <li>Signature encoding: IEEE_P1363 (this is the encoding that JWS and WebCrypto use). 186 * <li>Prefix type: {@link OutputPrefixType.TINK} 187 * </ul> 188 */ 189 public static final KeyTemplate ECDSA_P521_IEEE_P1363 = 190 createEcdsaKeyTemplate( 191 HashType.SHA512, 192 EllipticCurveType.NIST_P521, 193 EcdsaSignatureEncoding.IEEE_P1363, 194 OutputPrefixType.TINK); 195 196 /** 197 * A {@link KeyTemplate} that generates new instances of {@link 198 * com.google.crypto.tink.proto.Ed25519PrivateKey}. 199 * 200 * @since 1.1.0 201 */ 202 public static final KeyTemplate ED25519 = 203 KeyTemplate.newBuilder() 204 .setTypeUrl(Ed25519PrivateKeyManager.getKeyType()) 205 .setOutputPrefixType(OutputPrefixType.TINK) 206 .build(); 207 208 /** 209 * A {@link KeyTemplate} that generates new instances of {@link 210 * com.google.crypto.tink.proto.ED25519PrivateKey}. 211 * 212 * <p>The difference between {@link ED25519WithRawOutput} and {@link ED25519} is the format of 213 * signatures generated. {@link ED25519WithRawOutput} generates signatures of {@link 214 * OutputPrefixType.RAW} format, which is 64 bytes long. 215 * 216 * @since 1.3.0 217 */ 218 public static final KeyTemplate ED25519WithRawOutput = 219 KeyTemplate.newBuilder() 220 .setTypeUrl(Ed25519PrivateKeyManager.getKeyType()) 221 .setOutputPrefixType(OutputPrefixType.RAW) 222 .build(); 223 224 /** 225 * @return a {@link KeyTemplate} containing a {@link EcdsaKeyFormat} with some specified 226 * parameters. 227 * @deprecated Use a corresponding {@link EcdsaParameters} object instead. 228 */ 229 @Deprecated createEcdsaKeyTemplate( HashType hashType, EllipticCurveType curve, EcdsaSignatureEncoding encoding, OutputPrefixType prefixType)230 public static KeyTemplate createEcdsaKeyTemplate( 231 HashType hashType, 232 EllipticCurveType curve, 233 EcdsaSignatureEncoding encoding, 234 OutputPrefixType prefixType) { 235 EcdsaParams params = 236 EcdsaParams.newBuilder() 237 .setHashType(hashType) 238 .setCurve(curve) 239 .setEncoding(encoding) 240 .build(); 241 EcdsaKeyFormat format = EcdsaKeyFormat.newBuilder().setParams(params).build(); 242 return KeyTemplate.newBuilder() 243 .setValue(format.toByteString()) 244 .setTypeUrl(EcdsaSignKeyManager.getKeyType()) 245 .setOutputPrefixType(prefixType) 246 .build(); 247 } 248 249 /** 250 * A {@link KeyTemplate} that generates new instances of {@link 251 * com.google.crypto.tink.proto.RsaSsaPkcs1PrivateKey} with the following parameters: 252 * 253 * <ul> 254 * <li>Hash function: SHA256. 255 * <li>Modulus size: 3072 bit. 256 * <li>Public exponent: 65537 (aka F4). 257 * <li>Prefix type: {@link OutputPrefixType.TINK} 258 * </ul> 259 */ 260 public static final KeyTemplate RSA_SSA_PKCS1_3072_SHA256_F4 = 261 createRsaSsaPkcs1KeyTemplate( 262 HashType.SHA256, 3072, RSAKeyGenParameterSpec.F4, OutputPrefixType.TINK); 263 264 /** 265 * A {@link KeyTemplate} that generates new instances of {@link 266 * com.google.crypto.tink.proto.RsaSsaPkcs1PrivateKey} with the following parameters: 267 * 268 * <ul> 269 * <li>Hash function: SHA256. 270 * <li>Modulus size: 3072 bit. 271 * <li>Public exponent: 65537 (aka F4). 272 * <li>Prefix type: None 273 * </ul> 274 */ 275 public static final KeyTemplate RSA_SSA_PKCS1_3072_SHA256_F4_WITHOUT_PREFIX = 276 createRsaSsaPkcs1KeyTemplate( 277 HashType.SHA256, 3072, RSAKeyGenParameterSpec.F4, OutputPrefixType.RAW); 278 279 /** 280 * A {@link KeyTemplate} that generates new instances of {@link 281 * com.google.crypto.tink.proto.RsaSsaPkcs1PrivateKey} with the following parameters: 282 * 283 * <ul> 284 * <li>Hash function: SHA512. 285 * <li>Modulus size: 4096 bit. 286 * <li>Public exponent: 65537 (aka F4). 287 * <li>Prefix type: {@link OutputPrefixType.TINK} 288 * </ul> 289 */ 290 public static final KeyTemplate RSA_SSA_PKCS1_4096_SHA512_F4 = 291 createRsaSsaPkcs1KeyTemplate( 292 HashType.SHA512, 4096, RSAKeyGenParameterSpec.F4, OutputPrefixType.TINK); 293 294 /** 295 * @return a {@link KeyTemplate} containing a {@link RsaSsaPkcs1KeyFormat} with some specified 296 * parameters. 297 * @deprecated Use a corresponding {@link RsaSsaPkcs1Parameters} object instead 298 */ 299 @Deprecated createRsaSsaPkcs1KeyTemplate( HashType hashType, int modulusSize, BigInteger publicExponent, OutputPrefixType prefixType)300 public static KeyTemplate createRsaSsaPkcs1KeyTemplate( 301 HashType hashType, int modulusSize, BigInteger publicExponent, OutputPrefixType prefixType) { 302 RsaSsaPkcs1Params params = RsaSsaPkcs1Params.newBuilder().setHashType(hashType).build(); 303 RsaSsaPkcs1KeyFormat format = 304 RsaSsaPkcs1KeyFormat.newBuilder() 305 .setParams(params) 306 .setModulusSizeInBits(modulusSize) 307 .setPublicExponent(ByteString.copyFrom(publicExponent.toByteArray())) 308 .build(); 309 return KeyTemplate.newBuilder() 310 .setValue(format.toByteString()) 311 .setTypeUrl(RsaSsaPkcs1SignKeyManager.getKeyType()) 312 .setOutputPrefixType(prefixType) 313 .build(); 314 } 315 316 /** 317 * A {@link KeyTemplate} that generates new instances of {@link 318 * com.google.crypto.tink.proto.RsaSsaPssPrivateKey} with the following parameters: 319 * 320 * <ul> 321 * <li>Signature hash: SHA256. 322 * <li>MGF1 hash: SHA256. 323 * <li>Salt length: 32 (i.e., SHA256's output length). 324 * <li>Modulus size: 3072 bit. 325 * <li>Public exponent: 65537 (aka F4). 326 * </ul> 327 */ 328 public static final KeyTemplate RSA_SSA_PSS_3072_SHA256_SHA256_32_F4 = 329 createRsaSsaPssKeyTemplate( 330 HashType.SHA256, HashType.SHA256, 32, 3072, RSAKeyGenParameterSpec.F4); 331 332 /** 333 * A {@link KeyTemplate} that generates new instances of {@link 334 * com.google.crypto.tink.proto.RsaSsaPssPrivateKey} with the following parameters: 335 * 336 * <ul> 337 * <li>Signature hash: SHA512. 338 * <li>MGF1 hash: SHA512. 339 * <li>Salt length: 64 (i.e., SHA512's output length). 340 * <li>Modulus size: 4096 bit. 341 * <li>Public exponent: 65537 (aka F4). 342 * </ul> 343 */ 344 public static final KeyTemplate RSA_SSA_PSS_4096_SHA512_SHA512_64_F4 = 345 createRsaSsaPssKeyTemplate( 346 HashType.SHA512, HashType.SHA512, 64, 4096, RSAKeyGenParameterSpec.F4); 347 348 /** 349 * @return a {@link KeyTemplate} containing a {@link RsaSsaPssKeyFormat} with some specified 350 * parameters. 351 * @deprecated Use a corresponding {@link RsaSsaPssParameters} object instead. 352 */ 353 @Deprecated createRsaSsaPssKeyTemplate( HashType sigHash, HashType mgf1Hash, int saltLength, int modulusSize, BigInteger publicExponent)354 public static KeyTemplate createRsaSsaPssKeyTemplate( 355 HashType sigHash, 356 HashType mgf1Hash, 357 int saltLength, 358 int modulusSize, 359 BigInteger publicExponent) { 360 RsaSsaPssParams params = 361 RsaSsaPssParams.newBuilder() 362 .setSigHash(sigHash) 363 .setMgf1Hash(mgf1Hash) 364 .setSaltLength(saltLength) 365 .build(); 366 RsaSsaPssKeyFormat format = 367 RsaSsaPssKeyFormat.newBuilder() 368 .setParams(params) 369 .setModulusSizeInBits(modulusSize) 370 .setPublicExponent(ByteString.copyFrom(publicExponent.toByteArray())) 371 .build(); 372 return KeyTemplate.newBuilder() 373 .setValue(format.toByteString()) 374 .setTypeUrl(RsaSsaPssSignKeyManager.getKeyType()) 375 .setOutputPrefixType(OutputPrefixType.TINK) 376 .build(); 377 } 378 SignatureKeyTemplates()379 private SignatureKeyTemplates() {} 380 } 381