説明
RSA暗号化には安全なパディングが必要です。NoPadding は決定的で、暗号文の改ざんに弱い方式です。PKCS#1 v1.5パディング(PKCS1Padding)では、復号エラーや処理時間からパディングの有効性を区別できると、Bleichenbacher攻撃などのパディングオラクル攻撃を受けるおそれがあります。攻撃者は応答の違いを利用し、暗号文を段階的に復号できます。
想定される影響
- 平文の漏えい: パディングオラクルを通じて、暗号化されたトークン、セッション鍵、個人情報などが読み取られるおそれがあります。
- 認証情報やトークンの窃取: ログイントークンやAPIキーの漏えいが、アカウントの侵害につながるおそれがあります。
- 完全性の損失: パディングのないRSAや脆弱なパディングにより、意味のある暗号文の改ざんが可能になる場合があります。
- 暗号保護の低下: OAEPの代わりに古いパディングを許可すると、システムの保護が弱まり、他の攻撃と組み合わされるおそれがあります。
対処方法
- OAEPパディングを使用してください:
Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding")。 - 可能な場合は
OAEPParameterSpecでSHA-256、MGF1のSHA-256、PSource.PSpecified.DEFAULTを明示してください。 - RSA暗号化コードの
"RSA"、"RSA/ECB/PKCS1Padding"、"RSA/ECB/NoPadding"をOAEPに置き換えてください。暗号化側と復号側のパラメーター、およびプロバイダーの対応を確認してください。 - 復号失敗の処理を統一し、エラーの違いがオラクルにならないようにしてください。
- 実際のサービスでは、データをAES-GCMで暗号化し、ランダムなセッション鍵をRSA-OAEPでラップするハイブリッド暗号化を使用してください。
- RSA鍵は2048ビット以上とし、JCA/JCEプロバイダーを適切に更新してください。
例
変更前
java
import javax.crypto.Cipher;
import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
public class InsecureRSAExample {
// 취약: PKCS#1 v1.5 패딩 사용
public static byte[] encryptPassword(String password, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding"); // BAD
cipher.init(Cipher.ENCRYPT_MODE, publicKey);
return cipher.doFinal(password.getBytes(StandardCharsets.UTF_8));
}
}
変更後
java
import javax.crypto.Cipher;
import javax.crypto.spec.OAEPParameterSpec;
import java.security.spec.MGF1ParameterSpec;
import javax.crypto.spec.PSource;
import java.nio.charset.StandardCharsets;
import java.security.PublicKey;
public class SecureRSAExample {
// 안전: OAEP(SHA-256, MGF1) 사용
public static byte[] encryptPassword(String password, PublicKey publicKey) throws Exception {
Cipher cipher = Cipher.getInstance("RSA/ECB/OAEPWithSHA-256AndMGF1Padding");
OAEPParameterSpec oaep = new OAEPParameterSpec(
"SHA-256",
"MGF1",
MGF1ParameterSpec.SHA256,
PSource.PSpecified.DEFAULT
);
cipher.init(Cipher.ENCRYPT_MODE, publicKey, oaep);
return cipher.doFinal(password.getBytes(StandardCharsets.UTF_8));
}
}
解説:
- 変更前: 復号側がパディングエラーを区別できる場合、PKCS#1 v1.5暗号化はパディングオラクル攻撃に利用されるおそれがあります。
NoPaddingも決定的で改ざんに弱いため、代替手段にしないでください。 - 変更後: OAEPのハッシュとMGF1のハッシュにSHA-256を明示しています。この例は暗号化のみを示すため、復号失敗の統一したエラー処理は別途実装してください。