Implement Spark-compatible `aes_encrypt`
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 4/5
- Thời gian dự kiến
- 3-5 ngày
- Mức phù hợp với người mới
- 45/100
Hướng nghiên cứu
Start by reading how existing Spark functions are registered in crates/spark/src/function/misc/ (group misc_funcs) and whether an aes_decrypt helper module already exists, since this issue asks for a shared mode/padding/key-check module. Cross-check the vectors against Spark's ExpressionImplUtils.java (aesEncrypt, aesInternal) and misc.scala before trusting the issue's examples, which are LLM-generated. Done looks like crates/sqllogictest/test_files/misc/aes_encrypt.slt covering the fixed-IV vectors, NULL/key-length/unsupported-pair errors, and round trips through aes_decrypt, plus #[user_doc] docs.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Part of #272 and apache/datafusion-comet#7300.
What the function does
aes_encrypt(expr, key[, mode[, padding[, iv[, aad]]]]) encrypts expr with AES and returns BINARY.
expr, key, iv and aad are BINARY; mode and padding are STRING (collated strings accepted from 4.0).
Through ImplicitCastInputTypes, string arguments for expr, key, iv and aad are cast to binary (their UTF-8
bytes). Defaults: mode = 'GCM', padding = 'DEFAULT', iv = '', aad = ''. Since 3.3.0 (iv and aad since
3.5.0). The result is NULL if any argument is NULL (StaticInvoke with null propagation).
Supported (mode, padding) pairs, both case-insensitive: ECB with PKCS/DEFAULT (AES/ECB/PKCS5Padding),
CBC with PKCS/DEFAULT (AES/CBC/PKCS5Padding), GCM with NONE/DEFAULT (AES/GCM/NoPadding, 128-bit tag).
The key must be 16, 24 or 32 bytes (AES-128/192/256). It is used as is, with no key derivation.
Output layout: ECB is the ciphertext only. CBC is iv (16 bytes) || ciphertext. GCM is
iv (12 bytes) || ciphertext || tag (16 bytes). If iv is empty, a random IV is drawn from SecureRandom, so CBC and
GCM output is nondeterministic. Only ECB, or CBC/GCM with an explicit IV, give fixed results.
Examples
Deterministic ones (from the ExpressionDescription, ExpressionImplUtilsSuite and DataFrameFunctionsSuite):
SELECT base64(aes_encrypt('Spark SQL', '1234567890abcdef', 'ECB', 'PKCS'));
-- 3lmwu+Mw0H3fi5NDvcu9lg==
SELECT base64(aes_encrypt('Spark', 'abcdefghijklmnop', 'ECB'));
-- 4Hv0UKCx6nfUeAoPZo1z+w==
SELECT base64(aes_encrypt('Spark', 'abcdefghijklmnop12345678', 'ECB'));
-- NeTYNgA+PCQBN50DA//O2w==
SELECT base64(aes_encrypt('Spark', 'abcdefghijklmnop12345678ABCDEFGH', 'ECB'));
-- 9J3iZbIxnmaG+OIA9Amd+A==
SELECT base64(aes_encrypt('', 'abcdefghijklmnop', 'ECB'));
-- jmTOhz8XTbskI/zYFFgOFQ==
SELECT base64(aes_encrypt('Spark', 'abcdefghijklmnop12345678ABCDEFGH', 'CBC', 'DEFAULT', unhex('00000000000000000000000000000000')));
-- AAAAAAAAAAAAAAAAAAAAAPSd4mWyMZ5mhvjiAPQJnfg=
SELECT base64(aes_encrypt('Spark', 'abcdefghijklmnop12345678ABCDEFGH', 'GCM', 'DEFAULT', unhex('000000000000000000000000')));
-- AAAAAAAAAAAAAAAAQiYi+sRNYDAOTjdSEcYBFsAWPL1f
SELECT base64(aes_encrypt('Spark', 'abcdefghijklmnop12345678ABCDEFGH', 'GCM', 'DEFAULT', unhex('000000000000000000000000'), 'This is an AAD mixed into the input'));
-- AAAAAAAAAAAAAAAAQiYi+sTLm7KD9UcZ2nlRdYDe/PX4
SELECT aes_encrypt(cast(null as string), 'abcdefghijklmnop');
-- NULL
Random-IV examples can only be checked by round trip, or by length:
SELECT cast(aes_decrypt(aes_encrypt('Spark', 'abcdefghijklmnop'), 'abcdefghijklmnop') AS STRING);
-- Spark
SELECT length(aes_encrypt('Spark', '0000111122223333')); -- 33 (12 IV + 5 + 16 tag), by code reading
SELECT length(aes_encrypt('Apache Spark', '1234567890abcdef', 'CBC')); -- 32 (16 IV + 16), by code reading
Edge cases to test
- NULL in each of the six arguments gives NULL. String vs binary
exprandkeygive the same bytes. - Key length other than 16/24/32 (0, 15, 17 bytes):
INVALID_PARAMETER_VALUE.AES_KEY_LENGTH, sqlState 22023,
"The value of parameter(s)keyinaes_encrypt/aes_decryptis invalid: expects a binary value with 16, 24 or
32 bytes, but got 17 bytes." The key is checked before the mode. - Unsupported pair (
'CBC','None','ECB','NoPadding','GCM','PKCS','GSM'):UNSUPPORTED_FEATURE.AES_MODE,
sqlState 0A000, "The feature is not supported: AES-CBC with the padding None by theaes_encrypt/aes_decrypt
function." The parameters echo the user's original casing. - Non-empty IV with ECB:
UNSUPPORTED_FEATURE.AES_MODE_IV(aes_encryptwith AES-ECB does not support
initialization vectors (IVs).). - Wrong IV length (5 bytes for CBC or GCM):
INVALID_PARAMETER_VALUE.AES_IV_LENGTHwith parameter`iv`and
"supports 16-byte CBC IVs and 12-byte GCM IVs, but got 5 bytes for CBC." - Non-empty AAD with ECB or CBC:
UNSUPPORTED_FEATURE.AES_MODE_AAD. Emptyiv/aad('') behave exactly like
the defaults, so ECB withiv = ''andaad = ''is accepted. - Any JCE failure becomes
INVALID_PARAMETER_VALUE.AES_CRYPTO_ERRORwith parameter`expr`, `key`and the JCE
message asdetailMessage. A Rust implementation can't reproduce those messages exactly; match the condition. - Empty plaintext: ECB and CBC produce one full padding block, GCM produces IV + tag only (28 bytes).
- Plaintext longer than one block (
This message is longer than a single AES block and should work fine.) and
multi-byte UTF-8 strings. - Literal and column for every argument, including per-row
mode,padding,keyandivcolumns. - Determinism: Spark does not mark
aes_encryptnondeterministic. A call where every argument is a literal is
constant-folded (StaticInvokeis foldable), so every row gets the same IV. With a column argument each row gets a
fresh IV. In DataFusion the UDF should beVolatile. Tests must round-trip or pass a fixed IV.
Differences across Spark versions
- 3.4: only ECB and GCM, signature
(expr, key[, mode[, padding]]). OnlyGeneralSecurityExceptionis mapped to
AES_CRYPTO_ERROR. - 3.5: adds CBC (SPARK-43038),
ivandaad,UNSUPPORTED_FEATURE.AES_MODE_IV,UNSUPPORTED_FEATURE.AES_MODE_AAD,
INVALID_PARAMETER_VALUE.AES_IV_LENGTH.IllegalArgumentExceptionfrom the JCE is also mapped to
AES_CRYPTO_ERROR. - 4.0:
mode/paddingaccept collated strings. No behavior change through 4.2.
Implementation notes
- Spark:
sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/misc.scala(AesEncrypt, a
RuntimeReplaceableoverStaticInvoke) and
sql/catalyst/src/main/java/org/apache/spark/sql/catalyst/expressions/ExpressionImplUtils.java
(aesEncrypt,aesInternal,CipherMode). Errors inQueryExecutionErrors.scala. - DataFusion core has no AES functions.
- Suggested crates: RustCrypto
aes,aes-gcm,cbc,ecb(withblock-paddingPKCS7, which matches JCE
PKCS5Paddingfor 16-byte blocks). Random IVs fromrand(already a dependency) with an OS RNG. - Put it in
crates/spark/src/function/misc/(Spark groupmisc_funcs), sharing a helper module with
aes_decryptandtry_aes_decryptfor mode/padding parsing, key checks and error construction. - Tests: add
crates/sqllogictest/test_files/misc/aes_encrypt.sltwith the fixed-IV and ECB vectors above and
round-trip tests throughaes_decrypt; document with#[user_doc].
This issue was generated by an LLM (Claude) from the Apache Spark source code and tests. Examples come from Spark's ExpressionDescription examples, test suites and .sql.out golden files, but please verify them against Spark before relying on them.
- Ngôn ngữ chính
- Rust
- Star
- 7
- Fork
- 15
- Merge trung bình
- 16 giờ 43 phút
- Pull request đã merge (30 ngày)
- 26
Chuẩn bị môi trường
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của apache/datafusion-spark
-
enhancement
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
apache/datafusion-spark#287 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement good first issue
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 80/100
apache/datafusion-spark#266 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug] make_dt_interval returns NULL for more than about 1.49 million days, Spark returns the intervalCó thể đã có người làm @Subodh-17 đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
apache/datafusion-spark#109 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 5/5 Hơn một tuần Mức phù hợp với người mới 18/100
apache/datafusion-spark#299 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
enhancement
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 35/100
apache/datafusion-spark#298 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của apache/datafusion-spark
Issue tương tự
-
comp-rbac
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
ClickHouse/ClickHouse#131875 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
bug(python): read_transaction raises TypeError on a Rewrite with rewritten indicesCó thể đã có người làm @Borg93 đã nhận hôm nay. Đang mởbug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 75/100
lance-format/lance#11117 ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
storytold/photocraft#15232 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
forge: fork preflight reads still send `requireCanonical: false`, which Rootstock rejects (-32603)Có thể đã có người làm @Ynyesto đã nhận hôm nay. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
foundry-rs/foundry#18485 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
bondybondbond/rushcut#238 · 1 bình luận ·