CLOVER🍀

That was when it all began.

MessageDigestに"SHA"とか、Cipherに"AES"とだけ指定した場合、どうなるの?

これは、なにをしたくて書いたもの?

このあたりを見ていて

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9.1%2B1/src/java.base/share/classes/sun/security/provider/SecureRandom.java#L96-L116

digest = MessageDigest.getInstance("SHA");

MessageDigestを使う時は、今まで具体的なアルゴリズム名を指定して使ったことしかなったので、こういう指定の時に
実体としてはどうなるのかな?と思いまして。

あと、調べていたらCipherについてもこんな指定ができるようです。

Cipher cipher = Cipher.getInstance("AES");

こちらもモードとかパディングは指定するものだと思っていたので、こういう指定だとどういう構成になるのかをちゃんと
知らないなぁと。

簡単にjshellアルゴリズム名を見ても、SHAAESとしかわかりません。

jshell> java.security.MessageDigest.getInstance("SHA").getAlgorithm()
$1 ==> "SHA"

jshell> javax.crypto.Cipher.getInstance("AES").getAlgorithm()
$2 ==> "AES"

いったいあなた方は何者なのでしょう?

というわけで、このような使い方をした場合のMessageDigestCipherがどのような構成になるかを見てみたいと思います。

MessageDigestとSHA

MessageDigestJavadocを見てみましょう。

MessageDigest (Java SE 11 & JDK 11 )

MessageDigestで使えるアルゴリズムはこちらです。

Javaセキュリティ標準アルゴリズム名 / MessageDigestアルゴリズム

Javadocにも、こちらのドキュメントにもSHAという名前は登場しません。

JCAJDKプロバイダのドキュメントを見ても、書いていません。

Java暗号化アーキテクチャ(JCA)リファレンス・ガイド / MessageDigestクラス

JDKプロバイダ・ドキュメント / SUNプロバイダ

さて、これはなんなのでしょう?

CipherとAES

続いて、CipherJavadocを見てみます。こちらは書いてありました。アルゴリズムだけでも指定可能です。

変換は、次の書式で記述されます。

・"algorithm/mode/padding"または ・"algorithm"

後者の場合、モードおよびパディング方式には、プロバイダ固有のデフォルト値が使用されます。

Cipher (Java SE 11 & JDK 11 )

ただ、デフォルト値がなにかはJavadocからはわかりません。Javaセキュリティ標準アルゴリズム名を見てもわかりません。

Javaセキュリティ標準アルゴリズム名 / Cipherアルゴリズム名

JCAJDKプロバイダのドキュメントを見ると、答えが書いてあります。

Java暗号化アーキテクチャ(JCA)リファレンス・ガイド / Cipherクラス

アルゴリズム、モードおよびパディングを完全に指定した変換を使用することをお薦めします。そうしないと、プロバイダはデフォルトを使用します。たとえば、SunJCEプロバイダとSunPKCS11プロバイダは、多くの対称暗号でECBをデフォルト・モードとして、PKCS5Paddingをデフォルト・パディングとして使用します。

Java暗号化アーキテクチャ(JCA)リファレンス・ガイド / Cipherオブジェクトの作成

javax.crypto.Cipher.getInstance(String transformation)ファクトリ・メソッドは、algorithm/mode/padding形式の変換を使用してCipherオブジェクトを生成します。モード/パディングを省略すると、SunJCEプロバイダとSunPKCS11プロバイダは、多くの対称暗号でECBをデフォルト・モードとして、PKCS5Paddingをデフォルト・パディングとして使用します。

JDKプロバイダ・ドキュメント / 暗号の変換

つまり、AESと指定した場合はAES/ECB/PKCS5Paddingとなるようです。

こう見ると、ドキュメントに記載のある通りちゃんとモードとパディングを指定するのが正解のようですね(ECBを選ばない)。

MessageDigestの方も含めて、実際の動作を確認してみましょう。

環境

今回の環境は、こちら。

$ java --version
openjdk 11.0.9.1 2020-11-04
OpenJDK Runtime Environment (build 11.0.9.1+1-Ubuntu-0ubuntu1.20.04)
OpenJDK 64-Bit Server VM (build 11.0.9.1+1-Ubuntu-0ubuntu1.20.04, mixed mode, sharing)

MessageDigestでSHAのアルゴリズムをひととおり使う

では、最初はMessageDigestから確認してみましょう。

こんなプログラムを用意。
MessageDigestSample.java

import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

public class MessageDigestSample {
    public static void main(String... args) throws Exception {
        String targetValue = "Hello World";

        printDigest(MessageDigest.getInstance("SHA"), targetValue);
        printDigest(MessageDigest.getInstance("SHA-1"), targetValue);
        printDigest(MessageDigest.getInstance("SHA-224"), targetValue);
        printDigest(MessageDigest.getInstance("SHA-256"), targetValue);
        printDigest(MessageDigest.getInstance("SHA-384"), targetValue);
        printDigest(MessageDigest.getInstance("SHA-512/224"), targetValue);
        printDigest(MessageDigest.getInstance("SHA-512/256"), targetValue);
    }

    private static void printDigest(MessageDigest md, String targetValue) throws Exception {
        md.update(targetValue.getBytes(StandardCharsets.UTF_8));
        byte[] digest = md.digest();

        StringBuilder builder = new StringBuilder();

        for (byte b : digest) {
            builder.append(Integer.toHexString(0xff & b));
        }

        String digestAsString = builder.toString();

        System.out.printf("Input: %s, Algorithm: %s, Digest: %s%n", targetValue, md.getAlgorithm(), digestAsString);
    }
}

同じ値に対して、Javaセキュリティ標準アルゴリズム名 / MessageDigestアルゴリズムに記載されているすべてのアルゴリズムに加え、SHAを使っています。

実行。

$ java MessageDigestSample.java
Input: Hello World, Algorithm: SHA, Digest: a4d55a8d778e522fab701977c5d840bbc486d0
Input: Hello World, Algorithm: SHA-1, Digest: a4d55a8d778e522fab701977c5d840bbc486d0
Input: Hello World, Algorithm: SHA-224, Digest: c489faffdb0105d991a461e668e276685401b2eab1ef4372795047
Input: Hello World, Algorithm: SHA-256, Digest: a591a6d4bf420404a11733cfb7b190d62c65bfbcda32b57b277d9ad9f146e
Input: Hello World, Algorithm: SHA-384, Digest: 99514329186b2f6ae4a1329e7ee6c610a729636335174ac6b740f928396fcc83d0e93863a7c3d9f86beee782f4f3f
Input: Hello World, Algorithm: SHA-512/224, Digest: feca4195c80a571ae782f96bcef9ab81bdf182509a6844f32c4c17
Input: Hello World, Algorithm: SHA-512/256, Digest: ff2018851481c25bfc2e5d0c1e1fa57dac2a237a1a96192f99a10da47aa5442

これを見ると、どうやらSHASHA-1と同じようです。

他に確認する方法はないでしょうか。ちょっと、Provider#Serviceを出力してみましょう。

Security (Java SE 11 & JDK 11 )

Provider (Java SE 11 & JDK 11 )

Provider.Service (Java SE 11 & JDK 11 )

こんなプログラムを用意。
PrintSecurityProviders.java

import java.security.Provider;
import java.security.Security;

public class PrintSecurityProviders {
    public static void main(String... args) {
        for (Provider provider : Security.getProviders()) {
            for (Provider.Service service : provider.getServices()) {
                System.out.printf("Provider: %s, class: %s%n", provider.getName(), provider.getClass());
                System.out.println(service);
            }
        }
    }
}

実行して、MessageDigest.SHAが含まれている内容を探してみます。

$ java PrintSecurityProviders.java | grep MessageDigest.SHA -A 3 -B 1
Provider: SUN, class: class sun.security.provider.Sun
SUN: MessageDigest.SHA3-224 -> sun.security.provider.SHA3$SHA224
  aliases: [2.16.840.1.101.3.4.2.7, OID.2.16.840.1.101.3.4.2.7]
  attributes: {ImplementedIn=Software}

--
Provider: SUN, class: class sun.security.provider.Sun
SUN: MessageDigest.SHA3-384 -> sun.security.provider.SHA3$SHA384
  aliases: [2.16.840.1.101.3.4.2.9, OID.2.16.840.1.101.3.4.2.9]
  attributes: {ImplementedIn=Software}

Provider: SUN, class: class sun.security.provider.Sun
SUN: MessageDigest.SHA3-256 -> sun.security.provider.SHA3$SHA256
  aliases: [2.16.840.1.101.3.4.2.8, OID.2.16.840.1.101.3.4.2.8]
  attributes: {ImplementedIn=Software}

--
Provider: SUN, class: class sun.security.provider.Sun
SUN: MessageDigest.SHA-512 -> sun.security.provider.SHA5$SHA512
  aliases: [2.16.840.1.101.3.4.2.3, OID.2.16.840.1.101.3.4.2.3]
  attributes: {ImplementedIn=Software}

--
Provider: SUN, class: class sun.security.provider.Sun
SUN: MessageDigest.SHA -> sun.security.provider.SHA
  aliases: [1.3.14.3.2.26, SHA-1, SHA1, OID.1.3.14.3.2.26]
  attributes: {ImplementedIn=Software}

--
Provider: SUN, class: class sun.security.provider.Sun
SUN: MessageDigest.SHA-512/256 -> sun.security.provider.SHA5$SHA512_256
  aliases: [2.16.840.1.101.3.4.2.6, OID.2.16.840.1.101.3.4.2.6]
  attributes: {ImplementedIn=Software}

--
Provider: SUN, class: class sun.security.provider.Sun
SUN: MessageDigest.SHA3-512 -> sun.security.provider.SHA3$SHA512
  aliases: [2.16.840.1.101.3.4.2.10, OID.2.16.840.1.101.3.4.2.10]
  attributes: {ImplementedIn=Software}

Provider: SUN, class: class sun.security.provider.Sun
SUN: MessageDigest.SHA-384 -> sun.security.provider.SHA5$SHA384
  aliases: [2.16.840.1.101.3.4.2.2, OID.2.16.840.1.101.3.4.2.2]
  attributes: {ImplementedIn=Software}

Provider: SUN, class: class sun.security.provider.Sun
SUN: MessageDigest.SHA-256 -> sun.security.provider.SHA2$SHA256
  aliases: [2.16.840.1.101.3.4.2.1, OID.2.16.840.1.101.3.4.2.1]
  attributes: {ImplementedIn=Software}

--
Provider: SUN, class: class sun.security.provider.Sun
SUN: MessageDigest.SHA-512/224 -> sun.security.provider.SHA5$SHA512_224
  aliases: [2.16.840.1.101.3.4.2.5, OID.2.16.840.1.101.3.4.2.5]
  attributes: {ImplementedIn=Software}

Provider: SUN, class: class sun.security.provider.Sun
SUN: MessageDigest.SHA-224 -> sun.security.provider.SHA2$SHA224
  aliases: [2.16.840.1.101.3.4.2.4, OID.2.16.840.1.101.3.4.2.4]
  attributes: {ImplementedIn=Software}

ここですね。

Provider: SUN, class: class sun.security.provider.Sun
SUN: MessageDigest.SHA -> sun.security.provider.SHA
  aliases: [1.3.14.3.2.26, SHA-1, SHA1, OID.1.3.14.3.2.26]
  attributes: {ImplementedIn=Software}

SHAエイリアスとして、SHA-1SHA1が登録されているようです。

ソースコードでいくと、ここですね。

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9.1%2B1/src/java.base/share/classes/sun/security/provider/SunEntries.java#L207-L208

というわけで、SHASHA-1であることが、動作確認としてもプロバイダー定義としても、ソースコードとしても
確認できました。

CipherでAESのモード、パディングをひととおり使う

続いて、CipherAESも確認してみましょう。

こういうプログラムを用意。 CipherSample.java

CipherSample.java 
import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.IvParameterSpec;

public class CipherSample {
    public static void main(String... args) throws Exception {
        String targetValue = "Hello World!!!!!";

        KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
        keyGenerator.init(128);
        SecretKey key = keyGenerator.generateKey();

        SecureRandom random = new SecureRandom();
        byte[] ivBytes = new byte[16];
        random.nextBytes(ivBytes);
        IvParameterSpec iv = new IvParameterSpec(ivBytes);

        printEncrypted(Cipher.getInstance("AES"), key, null, targetValue);
        printEncrypted(Cipher.getInstance("AES/ECB/NoPadding"), key, null, targetValue);
        printEncrypted(Cipher.getInstance("AES/ECB/PKCS5Padding"), key, null, targetValue);
        printEncrypted(Cipher.getInstance("AES/CBC/NoPadding"), key, iv, targetValue);
        printEncrypted(Cipher.getInstance("AES/CBC/PKCS5Padding"), key, iv, targetValue);
    }

    private static void printEncrypted(Cipher cipher, SecretKey key, IvParameterSpec iv, String targetValue) throws Exception {
        cipher.init(Cipher.ENCRYPT_MODE, key, iv);
       
        byte[] encrypted = cipher.doFinal(targetValue.getBytes(StandardCharsets.UTF_8));

        StringBuilder builder = new StringBuilder();

        for (byte b : encrypted) {
            builder.append(Integer.toHexString(0xff & b));
        }

        String encryptedAsString = builder.toString();

        System.out.printf("Input: %s, Algorithm:  %s, Encrypted: %s%n", targetValue, cipher.getAlgorithm(), encryptedAsString);
    }
}

Javadocに記載されているAESのモード、パディングをGCMを除いてすべて使い、同じ値を暗号化します。

Cipher (Java SE 11 & JDK 11 )

鍵はランダムで生成しますが、各アルゴリズム、モード、パディングで同じものを使います。IVは、IVを要求するパターンだけ
ランダムで生成して同じものを渡します(IVが不要なECBにIVを渡すと例外がスローされます)。

実行してみます。
※鍵やIVをランダムに作っているので、実行するごとに結果が変わります

$ java CipherSample.java 
Input: Hello World!!!!!, Algorithm:  AES, Encrypted: c8b93e63c474e11fdd5019f693c3fcdaae4491828f5f7b6d8648514dbe8a7
Input: Hello World!!!!!, Algorithm:  AES/ECB/NoPadding, Encrypted: c8b93e63c474e11fdd5019f693c3fc
Input: Hello World!!!!!, Algorithm:  AES/ECB/PKCS5Padding, Encrypted: c8b93e63c474e11fdd5019f693c3fcdaae4491828f5f7b6d8648514dbe8a7
Input: Hello World!!!!!, Algorithm:  AES/CBC/NoPadding, Encrypted: daaaad8cfe7191c28b74fbe29d4896f1
Input: Hello World!!!!!, Algorithm:  AES/CBC/PKCS5Padding, Encrypted: daaaad8cfe7191c28b74fbe29d4896f1e399f94d81e37ce4d79df132ed39a3f

JCAJDKプロバイダのドキュメントに書かれていた通り、AESAES/ECB/PKCS5Paddingは同じのようです。

利用できるProvider#Serviceのうち、Cipher.AESに関するものを出力してみましょう。

$ java PrintSecurityProviders.java | grep Cipher.AES -A 3 -B 1
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_192/CBC/NoPadding -> com.sun.crypto.provider.AESCipher$AES192_CBC_NoPadding
  aliases: [2.16.840.1.101.3.4.1.22, OID.2.16.840.1.101.3.4.1.22]
  attributes: {SupportedKeyFormats=RAW}

Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_192/OFB/NoPadding -> com.sun.crypto.provider.AESCipher$AES192_OFB_NoPadding
  aliases: [2.16.840.1.101.3.4.1.23, OID.2.16.840.1.101.3.4.1.23]
  attributes: {SupportedKeyFormats=RAW}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_192/CFB/NoPadding -> com.sun.crypto.provider.AESCipher$AES192_CFB_NoPadding
  aliases: [2.16.840.1.101.3.4.1.24, OID.2.16.840.1.101.3.4.1.24]
  attributes: {SupportedKeyFormats=RAW}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AESWrap_192 -> com.sun.crypto.provider.AESWrapCipher$AES192
  aliases: [2.16.840.1.101.3.4.1.25, OID.2.16.840.1.101.3.4.1.25]
  attributes: {SupportedKeyFormats=RAW, SupportedModes=ECB, SupportedPaddings=NOPADDING}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_192/ECB/NoPadding -> com.sun.crypto.provider.AESCipher$AES192_ECB_NoPadding
  aliases: [2.16.840.1.101.3.4.1.21, OID.2.16.840.1.101.3.4.1.21]
  attributes: {SupportedKeyFormats=RAW}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_192/GCM/NoPadding -> com.sun.crypto.provider.AESCipher$AES192_GCM_NoPadding
  aliases: [2.16.840.1.101.3.4.1.26, OID.2.16.840.1.101.3.4.1.26]
  attributes: {SupportedKeyFormats=RAW}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_128/ECB/NoPadding -> com.sun.crypto.provider.AESCipher$AES128_ECB_NoPadding
  aliases: [2.16.840.1.101.3.4.1.1, OID.2.16.840.1.101.3.4.1.1]
  attributes: {SupportedKeyFormats=RAW}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_128/OFB/NoPadding -> com.sun.crypto.provider.AESCipher$AES128_OFB_NoPadding
  aliases: [2.16.840.1.101.3.4.1.3, OID.2.16.840.1.101.3.4.1.3]
  attributes: {SupportedKeyFormats=RAW}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_128/CBC/NoPadding -> com.sun.crypto.provider.AESCipher$AES128_CBC_NoPadding
  aliases: [2.16.840.1.101.3.4.1.2, OID.2.16.840.1.101.3.4.1.2]
  attributes: {SupportedKeyFormats=RAW}

Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AESWrap_128 -> com.sun.crypto.provider.AESWrapCipher$AES128
  aliases: [2.16.840.1.101.3.4.1.5, OID.2.16.840.1.101.3.4.1.5]
  attributes: {SupportedKeyFormats=RAW, SupportedModes=ECB, SupportedPaddings=NOPADDING}

Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_128/CFB/NoPadding -> com.sun.crypto.provider.AESCipher$AES128_CFB_NoPadding
  aliases: [2.16.840.1.101.3.4.1.4, OID.2.16.840.1.101.3.4.1.4]
  attributes: {SupportedKeyFormats=RAW}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_128/GCM/NoPadding -> com.sun.crypto.provider.AESCipher$AES128_GCM_NoPadding
  aliases: [2.16.840.1.101.3.4.1.6, OID.2.16.840.1.101.3.4.1.6]
  attributes: {SupportedKeyFormats=RAW}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_256/GCM/NoPadding -> com.sun.crypto.provider.AESCipher$AES256_GCM_NoPadding
  aliases: [2.16.840.1.101.3.4.1.46, OID.2.16.840.1.101.3.4.1.46]
  attributes: {SupportedKeyFormats=RAW}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_256/CFB/NoPadding -> com.sun.crypto.provider.AESCipher$AES256_CFB_NoPadding
  aliases: [2.16.840.1.101.3.4.1.44, OID.2.16.840.1.101.3.4.1.44]
  attributes: {SupportedKeyFormats=RAW}

Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AESWrap_256 -> com.sun.crypto.provider.AESWrapCipher$AES256
  aliases: [2.16.840.1.101.3.4.1.45, OID.2.16.840.1.101.3.4.1.45]
  attributes: {SupportedKeyFormats=RAW, SupportedModes=ECB, SupportedPaddings=NOPADDING}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_256/ECB/NoPadding -> com.sun.crypto.provider.AESCipher$AES256_ECB_NoPadding
  aliases: [2.16.840.1.101.3.4.1.41, OID.2.16.840.1.101.3.4.1.41]
  attributes: {SupportedKeyFormats=RAW}

Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_256/CBC/NoPadding -> com.sun.crypto.provider.AESCipher$AES256_CBC_NoPadding
  aliases: [2.16.840.1.101.3.4.1.42, OID.2.16.840.1.101.3.4.1.42]
  attributes: {SupportedKeyFormats=RAW}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES_256/OFB/NoPadding -> com.sun.crypto.provider.AESCipher$AES256_OFB_NoPadding
  aliases: [2.16.840.1.101.3.4.1.43, OID.2.16.840.1.101.3.4.1.43]
  attributes: {SupportedKeyFormats=RAW}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES -> com.sun.crypto.provider.AESCipher$General
  aliases: [Rijndael]
  attributes: {SupportedKeyFormats=RAW, SupportedModes=ECB|CBC|PCBC|CTR|CTS|CFB|OFB|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64|GCM|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128, SupportedPaddings=NOPADDING|PKCS5PADDING|ISO10126PADDING}

--
Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AESWrap -> com.sun.crypto.provider.AESWrapCipher$General
  attributes: {SupportedKeyFormats=RAW, SupportedModes=ECB, SupportedPaddings=NOPADDING}

Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE

最後の1行は余計でした…。こちらはSHAの時のようなエイリアスはないですね。

むしろ、Rijndaelってなってます。

Provider: SunJCE, class: class com.sun.crypto.provider.SunJCE
SunJCE: Cipher.AES -> com.sun.crypto.provider.AESCipher$General
  aliases: [Rijndael]
  attributes: {SupportedKeyFormats=RAW, SupportedModes=ECB|CBC|PCBC|CTR|CTS|CFB|OFB|CFB8|CFB16|CFB24|CFB32|CFB40|CFB48|CFB56|CFB64|OFB8|OFB16|OFB24|OFB32|OFB40|OFB48|OFB56|OFB64|GCM|CFB72|CFB80|CFB88|CFB96|CFB104|CFB112|CFB120|CFB128|OFB72|OFB80|OFB88|OFB96|OFB104|OFB112|OFB120|OFB128, SupportedPaddings=NOPADDING|PKCS5PADDING|ISO10126PADDING}

確かに。

jshell> javax.crypto.Cipher.getInstance("Rijndael").getAlgorithm()
$1 ==> "Rijndael"

なので、Rijndael/CBC/PKCS5Paddingといった指定も可能だったりします。

ソースコード上も確認してみましょう。

Cipher.AES_128/ECB/NoPaddingなどの、パディングなしの場合は固有にクラスがありますね。

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9.1%2B1/src/java.base/share/classes/com/sun/crypto/provider/AESCipher.java#L57-L145

そうでない場合は、こちらのようです。

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9.1%2B1/src/java.base/share/classes/com/sun/crypto/provider/AESCipher.java#L54

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9.1%2B1/src/java.base/share/classes/com/sun/crypto/provider/AESCipher.java#L185

キーサイズは-1です。-1は制限なし、を表すようですが…。

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9.1%2B1/src/java.base/share/classes/com/sun/crypto/provider/AESCipher.java#L173

で、肝心のデフォルト値はここを見るとわかります。

モードはECBですね。

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9.1%2B1/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java#L110

パディングは、PKCS5Paddingです。

https://github.com/openjdk/jdk11u/blob/jdk-11.0.9.1%2B1/src/java.base/share/classes/com/sun/crypto/provider/CipherCore.java#L164

というわけで、動作でもソースコード上でも確認できました、と。

まとめ

MessageDigestSHAとか、CipherAESとだけ指定した場合に、どうなるんだろう?という疑問からいろいろ調べて
みました。

動作確認から、実際のソースコードまで追って確認できたので、いい勉強になったなぁと思います。