-
Notifications
You must be signed in to change notification settings - Fork 26
Crypto updates #45
base: dev
Are you sure you want to change the base?
Crypto updates #45
Changes from all commits
568e41f
7a1802c
c513a02
775b4d8
34a5888
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package com.microsoft.azure.keyvault.cryptography.algorithms; | ||
|
|
||
| import java.security.KeyPair; | ||
|
|
||
| import com.microsoft.azure.keyvault.cryptography.ISignatureTransform; | ||
|
|
||
| public class Ps256 extends PsBase { | ||
|
|
||
| public final static String ALGORITHM_NAME = "PS256"; | ||
| public final static String DIGEST_HASH_NAME = "SHA-256"; | ||
|
|
||
| public Ps256() { | ||
| super(ALGORITHM_NAME); | ||
| } | ||
|
|
||
| @Override | ||
| public ISignatureTransform createSignatureTransform(KeyPair keyPair) { | ||
| return createSignatureTransform(keyPair, DIGEST_HASH_NAME); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| package com.microsoft.azure.keyvault.cryptography.algorithms; | ||
|
|
||
| import java.security.KeyPair; | ||
|
|
||
| import com.microsoft.azure.keyvault.cryptography.ISignatureTransform; | ||
|
|
||
| public class Ps384 extends PsBase { | ||
|
|
||
| public final static String ALGORITHM_NAME = "PS384"; | ||
| public final static String DIGEST_HASH_NAME = "SHA-384"; | ||
|
|
||
| public Ps384() { | ||
| super(ALGORITHM_NAME); | ||
| } | ||
|
|
||
| @Override | ||
| public ISignatureTransform createSignatureTransform(KeyPair keyPair) { | ||
| return createSignatureTransform(keyPair, DIGEST_HASH_NAME); | ||
| } | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package com.microsoft.azure.keyvault.cryptography.algorithms; | ||
|
|
||
| import java.security.KeyPair; | ||
|
|
||
| import com.microsoft.azure.keyvault.cryptography.ISignatureTransform; | ||
|
|
||
| public class Ps512 extends PsBase { | ||
| public final static String ALGORITHM_NAME = "PS512"; | ||
| public final static String DIGEST_HASH_NAME = "SHA-512"; | ||
|
|
||
| public Ps512() { | ||
| super(ALGORITHM_NAME); | ||
| } | ||
|
|
||
| @Override | ||
| public ISignatureTransform createSignatureTransform(KeyPair keyPair) { | ||
| return createSignatureTransform(keyPair, DIGEST_HASH_NAME); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,97 @@ | ||
| /** | ||
| * Copyright (c) Microsoft Corporation. All rights reserved. | ||
| * Licensed under the MIT License. See License.txt in the project root for | ||
| * license information. | ||
| */ | ||
|
|
||
| package com.microsoft.azure.keyvault.cryptography.algorithms; | ||
|
|
||
| import java.math.BigInteger; | ||
| import java.security.KeyPair; | ||
| import java.security.MessageDigest; | ||
| import java.security.NoSuchAlgorithmException; | ||
| import java.security.interfaces.RSAPrivateKey; | ||
| import java.security.interfaces.RSAPublicKey; | ||
| import java.security.spec.PSSParameterSpec; | ||
| import java.util.Arrays; | ||
| import java.util.zip.DataFormatException; | ||
| import java.security.Signature; | ||
|
|
||
| import com.microsoft.azure.keyvault.cryptography.ByteExtensions; | ||
| import com.microsoft.azure.keyvault.cryptography.ISignatureTransform; | ||
|
|
||
| /** | ||
| * | ||
| */ | ||
| public abstract class PsBase extends RsaSignature { | ||
|
|
||
| protected PsBase(String name) { | ||
| super(name); | ||
| } | ||
|
|
||
| class PsBaseSignatureTransform implements ISignatureTransform { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And RsaPssSignatureTransform for this one :-) |
||
|
|
||
| private final KeyPair _keyPair; | ||
| private final int _emLen; | ||
| private final int _modBits; | ||
| private final String _digestName; | ||
|
|
||
| PsBaseSignatureTransform(KeyPair keyPair, String digestName) { | ||
| _keyPair = keyPair; | ||
| BigInteger modulus = ((RSAPublicKey) _keyPair.getPublic()).getModulus(); | ||
| _emLen = getOctetLength(modulus.bitLength()); | ||
| _modBits = ((RSAPublicKey) _keyPair.getPublic()).getModulus().bitLength(); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. modulus was already extracted above, so _modBits is just modulus.bitLength(). And that was used in getOctetLength as well. So an opportunity to condense this a bit. |
||
| _digestName = digestName; | ||
| } | ||
|
|
||
| @Override | ||
| public byte[] sign(byte[] digest) throws NoSuchAlgorithmException { | ||
|
|
||
| if (_keyPair.getPrivate() == null) { | ||
| throw new IllegalArgumentException("Keypair must have private key to for signing."); | ||
| } | ||
|
|
||
| // Construct the encoded message | ||
| // Apply the EMSA-PSS encoding operation (Section | ||
| // 9.1.1) to the message M to produce an encoded message EM of length | ||
| // \ceil ((modBits - 1)/8) octets such that the bit length of the | ||
| // integer OS2IP (EM) (see Section 4.2) is at most modBits - 1, where | ||
| // modBits is the length in bits of the RSA modulus n: | ||
| MessageDigest messageDigest = MessageDigest.getInstance(_digestName); | ||
| byte[] EM = EMSA_PSS_ENCODE_HASH(digest, _modBits - 1, messageDigest); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Shouldn't EMSA_PSS_ENCODE use emBits rather than modBits? Where emBits would be emLen / 8? |
||
|
|
||
| // Convert to integer message | ||
| BigInteger m = OS2IP(EM); | ||
|
|
||
| // RSASP1(s) | ||
| m = RSASP1((RSAPrivateKey) _keyPair.getPrivate(), m); | ||
|
|
||
| // Convert to octet sequence | ||
| return I2OSP(m, _emLen); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean verify(byte[] digest, byte[] signature) throws NoSuchAlgorithmException { | ||
|
|
||
| if (signature.length != _emLen) { | ||
| throw new IllegalArgumentException("invalid signature length"); | ||
| } | ||
|
|
||
| // Convert to integer signature | ||
| BigInteger s = OS2IP(signature); | ||
|
|
||
| // Convert integer message | ||
| BigInteger m = RSAVP1((RSAPublicKey) _keyPair.getPublic(), s); | ||
|
|
||
| byte[] EM = I2OSP(m, _emLen); | ||
|
|
||
| MessageDigest messageDigest = MessageDigest.getInstance(_digestName); | ||
| return EMSA_PSS_VERIFY(digest, EM, _modBits, messageDigest); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
_modBits-1
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. EMSA-PSS-VERIFY is actually supposed to use emBits, not modBits. emBits is the bit length of EM, and in the ctor of we call getOctetLength to get _emLen which is the octet length of EM. In theory, emBits should always be the same as _emLen / 8. emBits and emLen are defined in https://tools.ietf.org/html/rfc3447#section-2 |
||
| } | ||
|
|
||
| } | ||
|
|
||
| public ISignatureTransform createSignatureTransform(KeyPair keyPair, String digestString) { | ||
| return new PsBaseSignatureTransform(keyPair, digestString); | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggest RsaPssSignature as the name for this class.