You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Erlang crypto:stream_init在32/64位系统密钥不一致的解决方法咨询

Fixing Cross-32/64-bit Erlang RC4 Encryption/Decryption Mismatch

Great question! This is a common gotcha when working with cross-bitwidth Erlang environments and the crypto module. Let’s break down the root cause and walk through the solutions to get consistent encryption/decryption across 32-bit and 64-bit systems.

Why the Mismatch Happens

The core issue is how crypto:stream_init(rc4, String) handles string inputs (Erlang lists) across different bitwidths. Erlang strings are lists of integers, and while you might expect this to work seamlessly, the implicit conversion of these lists to binary (required for RC4 key initialization) can have subtle, bitwidth-dependent inconsistencies in older Erlang versions. This leads to different RC4 stream states being generated on 32-bit vs 64-bit systems, making stream_encrypt and stream_decrypt produce mismatched results.

Step-by-Step Solutions

1. Use Binary Keys Explicitly

The most reliable fix is to stop passing strings (lists) directly to crypto:stream_init/2 and use binary keys instead. Binary representations are consistent across 32-bit and 64-bit systems, eliminating any implicit conversion issues.

Encryption Side (Any Bitwidth)

% Define your key as a binary instead of a string
KeyBin = <<"your_secure_secret_key">>,
% Initialize RC4 stream with the binary key
{RC4State, _} = crypto:stream_init(rc4, KeyBin),
% Encrypt your plaintext (ensure plaintext is also a binary!)
PlainTextBin = <<"Hello, cross-bitwidth world!">>,
{_, CipherText} = crypto:stream_encrypt(RC4State, PlainTextBin),

Decryption Side (Any Bitwidth)

% Use the EXACT same binary key as the encryption side
KeyBin = <<"your_secure_secret_key">>,
% Initialize RC4 stream identically
{RC4State, _} = crypto:stream_init(rc4, KeyBin),
% Decrypt the ciphertext
{_, PlainTextBin} = crypto:stream_decrypt(RC4State, CipherText),

2. Explicitly Convert Strings to Binaries (If You Must Use Strings)

If your key source is a string (e.g., user input, config files), explicitly convert it to a binary using a consistent method that works across bitwidths:

  • For ASCII strings (0-255), use list_to_binary/1
  • For Unicode strings, use unicode:characters_to_binary/1 with a specified encoding (like UTF-8)

Example:

% Start with a string key
KeyStr = "your_secure_secret_key",
% Convert to binary explicitly
KeyBin = list_to_binary(KeyStr),
% Proceed with stream initialization as before
{RC4State, _} = crypto:stream_init(rc4, KeyBin),

3. Verify Stream State Consistency

To confirm your fix works, you can hash the RC4 stream state on both systems to ensure they’re identical. This proves the initialization is consistent:

KeyBin = <<"your_secure_secret_key">>,
{RC4State, _} = crypto:stream_init(rc4, KeyBin),
% Generate a hash of the serialized state
StateHash = crypto:hash(sha256, term_to_binary(RC4State)),
io:format("RC4 State Hash: ~p~n", [StateHash]).

Run this on both 32-bit and 64-bit Erlang—if the hashes match, your stream initialization is consistent, and encryption/decryption will work as expected.

Key Notes

  • RC4 is a stream cipher, so stream_encrypt and stream_decrypt are functionally symmetric—what matters most is that both sides start with the exact same stream state.
  • Always ensure your plaintext/ciphertext is handled as binaries too, not strings—this avoids similar conversion issues.

内容的提问来源于stack exchange,提问作者Roman Rabinovich

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 10:38:51