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

Haskell中从PEM Base64编码字符串生成公/私钥问题求助

Hey, that StreamConstructionWrongSize error is super common when dealing with X509/PEM parsing in Haskell—usually boils down to issues with how you're handling the PEM data or ASN.1 decoding. Let's break down the most likely fixes and checks you can run:

1. Verify your PEM data is intact and correctly formatted

First, double-check that your Base64-encoded PEM string has:

  • The correct header/footer pairs (e.g., -----BEGIN CERTIFICATE----- and -----END CERTIFICATE----- for X509 certs, or -----BEGIN RSA PRIVATE KEY----- for PKCS#1 private keys)
  • No extra whitespace, line breaks, or truncated Base64 content
  • No non-ASCII characters (PEM is strictly ASCII-based)

You can quickly validate this with OpenSSL: save the PEM string to a file and run:

# For certificates
openssl x509 -in your-cert.pem -text -noout

# For RSA private keys
openssl rsa -in your-key.pem -text -noout

If OpenSSL throws an error, your PEM data is corrupted—fix that first before debugging your Haskell code.

2. Ensure you're parsing PEM correctly with Data.X509.PEM

It's easy to skip a step when extracting the actual X509 object from the PEM wrapper. Here's a robust example of parsing a certificate:

import Data.X509
import Data.X509.PEM
import qualified Data.ByteString as BS
import Data.String.Conversions (cs)

parseX509Cert :: String -> Either String X509Certificate
parseX509Cert pemString = do
    -- Convert String to ByteString (cs handles ASCII correctly here)
    let pemBS = cs pemString
    -- Parse PEM blocks
    pemBlocks <- case pemParseBS pemBS of
        Left err -> Left $ "Failed to parse PEM: " ++ err
        Right blocks -> Right blocks
    -- Filter for the certificate block (match the header label exactly)
    certBlock <- case filter (\block -> pemLabel block == "CERTIFICATE") pemBlocks of
        [] -> Left "No certificate block found in PEM data"
        [block] -> Right block
        _ -> Left "Multiple certificate blocks found—expected one"
    -- Decode the signed X509 object
    signedCert <- case decodeSignedObject (pemContent certBlock) of
        Left err -> Left $ "Failed to decode X509: " ++ show err
        Right obj -> Right obj
    -- Extract the actual certificate from the signed wrapper
    Right $ signedObject signedCert

For private keys, adjust the label to match your format: use "RSA PRIVATE KEY" for PKCS#1 keys, or "PRIVATE KEY" for PKCS#8 keys.

3. Fix common encoding mismatches

The StreamConstructionWrongSize error often pops up when you're using the wrong encoding to convert between String and ByteString. Since PEM is ASCII-only, Data.String.Conversions.cs should work, but if your input String has hidden non-ASCII characters (like smart quotes or invisible whitespace), that'll break the Base64 decoding.

Try explicitly converting with ASCII encoding instead to rule this out:

import Data.ByteString.Char8 (pack)

let pemBS = pack pemString  -- Pack String to ByteString using ASCII encoding

4. Use the right cryptonite functions for private keys

If you're working with private keys, make sure you're using the correct import function for your key format:

  • For PKCS#1 RSA keys: Use Crypto.PubKey.RSA.PKCS1.importKey
  • For PKCS#8 RSA keys: Use Crypto.PubKey.RSA.PKCS8.importKeyPair

Using the wrong function will lead to ASN.1 parsing errors like StreamConstructionWrongSize.

If you can share a bit more of your full code (or a sanitized version of your PEM data), I can help narrow this down even further!

内容的提问来源于stack exchange,提问作者blue robot

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:27:45