google / google/webcrypto.dart

[Android JCA] Support RSA PKCS#8 imports when providers hide CRT parameters

Open
#371 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Dart
Stars
116
Forks
110
Avg merge
6d 8h
Merged PRs (30d)
9

Description

## Problem

On the tested Android API 24-26 providers, `KeyFactory` accepts a valid RSA PKCS#8 encoding but returns a private-key object that does not implement `RSAPrivateCrtKey`. The JNI backend then rejects the key because its import-time validation and private JWK export require the CRT components.

The tested API 36 provider returns an `RSAPrivateCrtKey` for the same generate, encode, and re-import path.

## Provider Evidence

On the Android API 24 x86_64 image with AndroidOpenSSL 1.0:

- RSA generation returns `OpenSSLRSAPrivateCrtKey`.
- Re-importing the generated key's PKCS#8 encoding returns `OpenSSLRSAPrivateKey`.
- The imported key does not implement `RSAPrivateCrtKey`.
- `KeyFactory.getKeySpec(..., RSAPrivateCrtKeySpec.class)` returns a plain `RSAPrivateKeySpec`, so the provider still does not expose the CRT values.

API 25 and 26 reproduce the same `package:webcrypto` PKCS#8 import failure. API 36 re-imports the generated encoding as `OpenSSLRSAPrivateCrtKey` and passes the shared RSA-PSS suite with the parameter-order fix.

The shared RSA key layer affects RSASSA-PKCS1-v1_5, RSA-OAEP, and RSA-PSS.

## Constraint

The backend checks CRT consistency during import so malformed private keys fail as `FormatException` before use. Private JWK export requires `n`, `e`, `d`, `p`, `q`, `dp`, `dq`, and `qi`. Removing the CRT requirement would weaken import validation and leave private JWK export incomplete.

## Decision Needed

Choose one source for provider-independent RSA components:

- Add a small reviewed PKCS#8/DER parser to the JNI backend and retain the parsed components beside the persistent JCA key.
- Use a reviewed ASN.1 dependency for the same parse-and-retain design.
- Restrict the supported Android provider/API matrix and document the limitation.

The API 24 experiment rules out direct CRT extraction through `KeyFactory.getKeySpec`.

## Acceptance Criteria

- Valid generated and supplied PKCS#8 keys import on the selected Android provider/API matrix.
- Malformed RSA keys fail during import with `FormatException`.
- PKCS#8 and private JWK exports preserve the imported key material.
- Persistent JCA key ownership and isolate-unsendable behavior remain intact.
- Focused RSASSA, RSA-OAEP, and RSA-PSS tests pass.
- The shared RSA suites run on every Android API/provider combination selected for backend support.

## Reproduced Results

- API 24 x86_64 RSA-PSS selection: 22 passed and 344 failed after the private-key import prerequisite failed.
- API 25 and 26 x86_64 focused RSA-PSS tests fail at the same private-key import step.
- API 36 x86_64 RSA-PSS selection with the parameter-order fix: 366 passed.

Related: #323, #340, #341

Contributor guide

Open the contributing guide

Research direction

Start with the JNI backend's RSA import validation and private JWK export path, using the API 24–26 provider evidence as the baseline. Review the three proposed sources for provider-independent components and related issues #323, #340, and #341 before choosing an approach. Done means the selected provider/API matrix passes the focused RSASSA, RSA-OAEP, and RSA-PSS suites while preserving malformed-key rejection, exports, JCA ownership, and isolate-unsendable behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
android, dart, java
Domain
cryptography, mobile-dev, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.