|
Java example source code file (RSAPadding.java)
The RSAPadding.java Java example source code
/*
* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package sun.security.rsa;
import java.math.BigInteger;
import java.util.*;
import java.security.*;
import java.security.interfaces.*;
import java.security.spec.*;
import javax.crypto.BadPaddingException;
import javax.crypto.spec.PSource;
import javax.crypto.spec.OAEPParameterSpec;
import sun.security.jca.JCAUtil;
/**
* RSA padding and unpadding.
*
* Format of PKCS#1 v1.5 padding is:
* 0x00 | BT | PS...PS | 0x00 | data...data
* where BT is the blocktype (1 or 2). The length of the entire string
* must be the same as the size of the modulus (i.e. 128 byte for a 1024 bit
* key). Per spec, the padding string must be at least 8 bytes long. That
* leaves up to (length of key in bytes) - 11 bytes for the data.
*
* OAEP padding is a bit more complicated and has a number of options.
* We support:
* . arbitrary hash functions ('Hash' in the specification), MessageDigest
* implementation must be available
* . MGF1 as the mask generation function
* . the empty string as the default value for label L and whatever
* specified in javax.crypto.spec.OAEPParameterSpec
*
* Note: RSA keys should be at least 512 bits long
*
* @since 1.5
* @author Andreas Sterbenz
*/
public final class RSAPadding {
// NOTE: the constants below are embedded in the JCE RSACipher class
// file. Do not change without coordinating the update
// PKCS#1 v1.5 padding, blocktype 1 (signing)
public final static int PAD_BLOCKTYPE_1 = 1;
// PKCS#1 v1.5 padding, blocktype 2 (encryption)
public final static int PAD_BLOCKTYPE_2 = 2;
// nopadding. Does not do anything, but allows simpler RSACipher code
public final static int PAD_NONE = 3;
// PKCS#1 v2.1 OAEP padding
public final static int PAD_OAEP_MGF1 = 4;
// type, one of PAD_*
private final int type;
// size of the padded block (i.e. size of the modulus)
private final int paddedSize;
// PRNG used to generate padding bytes (PAD_BLOCKTYPE_2, PAD_OAEP_MGF1)
private SecureRandom random;
// maximum size of the data
private final int maxDataSize;
// OAEP: main messagedigest
private MessageDigest md;
// OAEP: message digest for MGF1
private MessageDigest mgfMd;
// OAEP: value of digest of data (user-supplied or zero-length) using md
private byte[] lHash;
/**
* Get a RSAPadding instance of the specified type.
* Keys used with this padding must be paddedSize bytes long.
*/
public static RSAPadding getInstance(int type, int paddedSize)
throws InvalidKeyException, InvalidAlgorithmParameterException {
return new RSAPadding(type, paddedSize, null, null);
}
/**
* Get a RSAPadding instance of the specified type.
* Keys used with this padding must be paddedSize bytes long.
*/
public static RSAPadding getInstance(int type, int paddedSize,
SecureRandom random) throws InvalidKeyException,
InvalidAlgorithmParameterException {
return new RSAPadding(type, paddedSize, random, null);
}
/**
* Get a RSAPadding instance of the specified type, which must be
* OAEP. Keys used with this padding must be paddedSize bytes long.
*/
public static RSAPadding getInstance(int type, int paddedSize,
SecureRandom random, OAEPParameterSpec spec)
throws InvalidKeyException, InvalidAlgorithmParameterException {
return new RSAPadding(type, paddedSize, random, spec);
}
// internal constructor
private RSAPadding(int type, int paddedSize, SecureRandom random,
OAEPParameterSpec spec) throws InvalidKeyException,
InvalidAlgorithmParameterException {
this.type = type;
this.paddedSize = paddedSize;
this.random = random;
if (paddedSize < 64) {
// sanity check, already verified in RSASignature/RSACipher
throw new InvalidKeyException("Padded size must be at least 64");
}
switch (type) {
case PAD_BLOCKTYPE_1:
case PAD_BLOCKTYPE_2:
maxDataSize = paddedSize - 11;
break;
case PAD_NONE:
maxDataSize = paddedSize;
break;
case PAD_OAEP_MGF1:
String mdName = "SHA-1";
String mgfMdName = "SHA-1";
byte[] digestInput = null;
try {
if (spec != null) {
mdName = spec.getDigestAlgorithm();
String mgfName = spec.getMGFAlgorithm();
if (!mgfName.equalsIgnoreCase("MGF1")) {
throw new InvalidAlgorithmParameterException
("Unsupported MGF algo: " + mgfName);
}
mgfMdName = ((MGF1ParameterSpec)spec.getMGFParameters()).getDigestAlgorithm();
PSource pSrc = spec.getPSource();
String pSrcAlgo = pSrc.getAlgorithm();
if (!pSrcAlgo.equalsIgnoreCase("PSpecified")) {
throw new InvalidAlgorithmParameterException
("Unsupported pSource algo: " + pSrcAlgo);
}
digestInput = ((PSource.PSpecified) pSrc).getValue();
}
md = MessageDigest.getInstance(mdName);
mgfMd = MessageDigest.getInstance(mgfMdName);
} catch (NoSuchAlgorithmException e) {
throw new InvalidKeyException
("Digest " + mdName + " not available", e);
}
lHash = getInitialHash(md, digestInput);
int digestLen = lHash.length;
maxDataSize = paddedSize - 2 - 2 * digestLen;
if (maxDataSize <= 0) {
throw new InvalidKeyException
("Key is too short for encryption using OAEPPadding" +
" with " + mdName + " and MGF1" + mgfMdName);
}
break;
default:
throw new InvalidKeyException("Invalid padding: " + type);
}
}
// cache of hashes of zero length data
private static final Map<String,byte[]> emptyHashes =
Collections.synchronizedMap(new HashMap<String,byte[]>());
/**
* Return the value of the digest using the specified message digest
* <code>md and the digest input
Other Java examples (source code examples)Here is a short list of links related to this Java RSAPadding.java source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.