Many Repairs, One Direction: Steering Code Models Toward Safer Cryptographic API Use
Organizations: University of Auckland Auckland, New Zealand
Abstract
Cryptographic API misuse in large language model-generated code can compromise software security. While many existing approaches improve code security by modifying model parameters or inputs, how representation changes associated with different cryptographic API repairs can support a shared intervention for safer code generation remains underexplored. To investigate this, we construct 48,000 matched program pairs across four programming languages and ten cryptographic API misuse categories. Each pair changes a specified API decision while preserving the programming task. Subtracting the misuse program's internal representation from its secure counterpart's gives a repair vector. Across five models, comparisons of mean repair vectors reveal stronger organization by misuse category than by language. These category-specific patterns also support a shared intervention. We introduce CrypSteer, which extracts a shared direction by normalizing repair differences and selecting a principal component aligned with repairs across misuse categories. With model weights fixed, adding one shared direction per model to its internal activations during generation improves aggregate target security rates by 5.28--15.00 percentage points over unsteered generation across languages and misuse categories. These findings connect the shared structure of cryptographic repair representations to a reusable intervention for safer code generation.
Figures & tables
| ID | Misuse definition | Dataset contrast (secure / misuse) |
|---|---|---|
| M01 | Predictable cryptographic keys | Random / fixed literal key |
| M02 | Insecure mode of encryption | CBC mode / ECB mode |
| M03 | Predictable IVs in CBC mode | Random / constant IV |
| M04 | Short cryptographic keys | 2048 / 1024 bits for RSA |
| M05 | Predictable random output | Cryptographic / general-purpose PRNG |
| M06 | Predictable salts for key derivation | Random / constant salt |
| Model | Mean cosine same category across languages | Mean cosine different categories within a language | Category matches | Norm ratio |
|---|---|---|---|---|
| Llama | 0.607 | 0.130 | 40/40 | 19.2 |
| CodeGemma | 0.673 | 0.111 | 40/40 | 22.5 |
| Qwen | 0.673 | 0.095 | 38/40 | 14.6 |
| Qwen-Coder | 0.694 | 0.118 | 38/40 | 14.3 |
| DeepSeek | 0.650 | 0.112 | 38/40 | 16.2 |
| Model | Positive repairs (%) | Mean cosine | Positive cells |
|---|---|---|---|
| Llama | 95.36 | 0.343 | 38/40 |
| CodeGemma | 88.86 | 0.332 | 36/40 |
| Qwen | 95.22 | 0.324 | 38/40 |
| Qwen-Coder | 91.11 | 0.318 | 37/40 |
| DeepSeek | 97.86 | 0.337 | 40/40 |
| Model | Java | TypeScript | C# | Python |
|---|---|---|---|---|
| Llama | 0.930 | 0.819 | 0.971 | 0.990 |
| CodeGemma | 0.770 | 0.615 | 0.838 | 0.946 |
| Qwen | 0.986 | 0.996 | 0.997 | 0.987 |
| Qwen-Coder | 0.950 | 0.964 | 0.866 | 0.986 |
| DeepSeek | 0.978 | 0.991 | 0.985 | 0.965 |
| Model | Metric (%) | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Baseline | Cell DiffMean | Pooled DiffMean | Normalized DiffMean | CrypSteer | Cell DiffMean | Pooled DiffMean | Normalized DiffMean | CrypSteer | ||
| Llama | secure@1 | 62.08 | 39.28 | 45.97 | 37.58 | 33.22 | 71.90 | 72.12 | 74.88 | 77.08 |
| valid@1 | 72.67 | 66.97 | 64.73 | 58.67 | 53.78 | 68.23 | 70.02 | 69.47 | 69.50 | |
| secure-valid@1 | 47.52 | 28.25 | 32.12 | 23.08 | 18.20 | 52.33 | 54.40 | 56.33 | 57.18 | |
| CodeGemma | secure@1 | 46.27 | 32.23 | 33.03 | 30.57 | 28.63 | 54.07 | 53.73 | 55.45 | 56.68 |
| valid@1 | 37.92 | 36.27 | 38.30 | 36.47 | 35.25 | 39.43 | 36.95 | 38.37 | 39.30 | |
| Excluded from direction fitting | |||||
|---|---|---|---|---|---|
| Model | Metric | None | Language | Misuse | Both |
| Llama | secure@1 | ||||
| secure-valid@1 | |||||
| Code Gemma | secure@1 | ||||
| secure-valid@1 | |||||
| Qwen | secure@1 | ||||
| Model | Method | secure@1 | valid@1 | secure- valid@1 |
|---|---|---|---|---|
| Llama | SCS-Code | 75.45 | 72.62 | 58.47 |
| Surgical Repair | 66.57 | 70.87 | 50.62 | |
| CrypSteer | 77.08 | 69.50 | 57.18 | |
| CodeGemma | SCS-Code | 51.50 | 40.35 | 25.02 |
| Surgical Repair | 51.20 | 39.58 | 23.80 | |
| CrypSteer | 56.68 | 39.30 | 26.53 |
Appendix figures & tables16 assets
Supplementary material from the paper’s appendix.
Appendix
| Functionality | Description | Categories |
|---|---|---|
| F1: Symmetric encryption | Encrypt and decrypt data with the same secret key. | M01, M02 |
| F2: Symmetric encryption in CBC mode | Encrypt data using cipher block chaining (CBC) and an IV. | M03 |
| F3: Asymmetric encryption | Encrypt with a public key and decrypt with the private key. | M04 |
| F4: Digital signature | Produce a signature with a private key and verify it with a public key. | M04 |
| F5: Hash functions | Compute a fixed-length digest for detecting changes to data. | M09 |
| F6: Message authentication code (MAC) | Compute a keyed authentication tag to check integrity and authenticity. | M01, M10 |
| Structure | Value placement | Construction |
|---|---|---|
| variable_inline | Variable | Inline |
| variable_helper | Variable | Helper return |
| callsite_inline | Call site | Inline |
| callsite_helper | Call site | Helper return |
| Model | Para- meters | Total layers | Selected layer | AUROC | Selected PC | |
|---|---|---|---|---|---|---|
| Llama | 8B | 32 | 14 | 0.783 | 1 | |
| CodeGemma | 7B | 28 | 18 | 0.803 | 1 | |
| Qwen | 7B | 28 | 17 | 0.793 | 2 | |
| Qwen-Coder | 7B | 28 | 16 | 0.821 | 1 | |
| DeepSeek | 16B | 27 | 11 | 0.784 | 1 |
| Model | Category main effect | Language main effect |
|---|---|---|
| Llama | 64.42% | 5.52% |
| CodeGemma | 70.80% | 4.67% |
| Qwen | 71.24% | 4.67% |
| Qwen-Coder | 72.39% | 4.57% |
| DeepSeek | 68.86% | 5.17% |
| Model | Category ARI | Language ARI |
|---|---|---|
| Llama | 0.565 | |
| CodeGemma | 0.657 | |
| Qwen | 0.771 | |
| Qwen-Coder | 0.798 | |
| DeepSeek | 0.895 |
| Model | Comparator | secure@1 | valid@1 | secure-valid@1 | |||
|---|---|---|---|---|---|---|---|
| Llama | Baseline | ||||||
| Cell DiffMean | |||||||
| Pooled DiffMean | |||||||
| Normalized DiffMean | |||||||
| CodeGemma | Baseline | ||||||
| Cell DiffMean | |||||||
| Baseline | Cell DiffMean | Pooled DiffMean | Normalized DiffMean | CrypSteer | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Model | Language | secure @1 | valid @1 | secure- valid@1 | secure @1 | valid @1 | secure- valid@1 | secure @1 | valid @1 | secure- valid@1 | secure @1 | valid @1 | secure- valid@1 | secure @1 | valid @1 | secure- valid@1 |
| Llama | Java | 53.53 | 59.87 | 33.47 | 74.33 | 55.47 | 42.60 | 76.73 | 59.00 | 46.53 | 81.00 | 57.67 | 48.93 | 81.33 | 57.00 | 48.33 |
| TypeScript | 62.00 | 73.47 | 48.47 | 68.07 | 66.60 | 52.87 | 63.80 | 67.53 | 52.73 | 68.27 | 67.67 | 55.20 | 72.07 | 67.47 | 56.47 | |
| C# | 62.67 | 70.47 | 43.93 | 70.67 | 68.93 | 49.47 | 71.80 | 67.33 | 49.40 | 72.93 | 67.87 | 52.20 | 74.47 | 68.07 | 52.27 | |
| Python | 70.13 | 86.87 | 64.20 | 74.53 | 81.93 | 64.40 | 76.13 | 86.20 | 68.93 | 77.33 | 84.67 | 69.00 | 80.47 | 85.47 | 71.67 | |
| CodeGemma | Java | 56.20 | 37.87 | 25.80 | 68.40 | 39.07 | 30.93 | 68.33 | 37.33 | 29.47 | 70.67 | 37.40 | 30.47 | 72.47 | 39.93 | 32.00 |
| Baseline | Cell DiffMean | Pooled DiffMean | Normalized DiffMean | CrypSteer | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Model | Category | secure @1 | valid @1 | secure- valid@1 | secure @1 | valid @1 | secure- valid@1 | secure @1 | valid @1 | secure- valid@1 | secure @1 | valid @1 | secure- valid@1 | secure @1 | valid @1 | secure- valid@1 |
| Llama | M01 | 55.17 | 66.17 | 43.17 | 68.00 | 59.50 | 45.67 | 66.33 | 63.17 | 49.33 | 68.50 | 61.00 | 48.17 | 67.33 | 57.67 | 43.33 |
| M02 | 73.17 | 63.67 | 48.50 | 78.67 | 65.50 | 56.50 | 70.50 | 59.00 | 50.00 | 77.50 | 61.00 | 56.33 | 82.33 | 64.00 | 61.17 | |
| M03 | 67.67 | 50.83 | 40.33 | 68.17 | 43.83 | 37.33 | 69.00 | 39.33 | 35.50 | 70.33 | 44.50 | 39.67 | 74.33 | 48.33 | 44.17 | |
| M04 | 63.67 | 64.50 | 44.50 | 82.67 | 54.33 | 51.33 | 80.33 | 68.17 | 59.67 | 82.33 | 63.83 | 58.50 | 83.33 | 60.17 | 56.83 | |
| M05 | 58.00 | 84.17 | 46.83 | 48.83 | 83.83 | 38.33 | 58.83 | 84.67 | 46.50 | 60.17 | 85.33 | 49.67 | 62.83 | 83.17 | 50.67 | |
| Model | Comparator | secure@1 | valid@1 | secure-valid@1 | |||
|---|---|---|---|---|---|---|---|
| Llama | SCS-Code | ||||||
| Surgical Repair | |||||||
| CodeGemma | SCS-Code | ||||||
| Surgical Repair | |||||||
| Qwen | SCS-Code | ||||||
| Surgical Repair | |||||||
| ID | Misuse | Secure use |
|---|---|---|
| M01 | Cryptographic key from a fixed string, fixed byte array, or general-purpose PRNG | Cryptographic key generated by a CSPRNG or derived by a KDF |
| M02 | AES with ECB mode | AES encryption with other secure modes, such as CBC, CTR, GCM, CCM, OFB, CFB |
| M03 | AES CBC encryption with IV from fixed bytes, a fixed string, or predictable randomness | AES CBC encryption with IV generated by a CSPRNG |
| M04 | RSA key size bits | RSA key size bits |
| M05 | General-purpose PRNG output or a predictable generator seed | CSPRNG output |
| M06 | Fixed salt, or predictably reused salt | Fresh random salt |
| Model | Activation extraction | Layer probes | Full-source generation | Source-exclusion generation |
|---|---|---|---|---|
| Llama | ||||
| CodeGemma | ||||
| Qwen | ||||
| Qwen-Coder | ||||
| DeepSeek |
Secure Code Generation
Secure code generation studies how to produce code that meets functional requirements while avoiding security vulnerabilities.
See all 48 papers