ppk-to-openssh
Version:
A pure JavaScript library for parsing and converting PuTTY private key files (.ppk) to OpenSSH format. Supports all PPK versions (v2 and v3) and key types (RSA, DSA, ECDSA, Ed25519). Handles both encrypted and unencrypted keys with full MAC verification.
274 lines (215 loc) • 12.4 kB
Markdown
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [3.2.0] - 2025-06-20
### Added
- **ES Modules Support**: Complete conversion to ES6 imports/exports for optimal webpack bundling
- **Tree Shaking**: Source code now uses import-only syntax enabling better dead code elimination
- **Build System**: Enhanced build process that generates both CommonJS and ES module outputs
- **Webpack Optimization**: Improved static analysis and smaller bundle sizes for modern bundlers
### Enhanced
- **Developer Experience**: Better import/export structure for modern development workflows
- **Bundle Performance**: Optimized for webpack and other ES module-aware bundlers
- **Backward Compatibility**: Maintains full CommonJS compatibility through dual exports
### Technical
- **Source Migration**: Converted all source files from CommonJS to ES modules
- **Build Scripts**: Added automated CommonJS generation from ES module sources
- **Code Quality**: Added ESLint configuration for ES module standards
- **Testing**: Updated test infrastructure to work with new module system
## [3.1.1] - 2025-06-19
### Fixed
- **Documentation**: Corrected API documentation in README.md for PPKParser class usage
- **API Reference**: Fixed PPKParser.parse() method signature to show correct 2-parameter usage
- **Constructor Options**: Added missing outputPassphrase option documentation for PPKParser constructor
- **API Clarity**: Added clear distinction between wrapper functions and PPKParser class APIs
### Enhanced
- **Examples**: Updated all PPKParser code examples to show correct parameter usage
- **Developer Experience**: Added warning section explaining API differences to prevent confusion
## [3.1.0] - 2025-06-19
### Fixed
- **Critical Encryption Bug**: Fixed encryption functionality where `encrypt: true` option was producing unencrypted output
- **OpenSSH Key Format**: Corrected cipher and KDF fields to use proper encryption values instead of 'none'
- **Key Derivation**: Implemented proper bcrypt-style key derivation for OpenSSH private key encryption
### Enhanced
- **Test Coverage**: Added comprehensive encryption tests to verify cipher and KDF values in output
- **Error Validation**: Improved error handling for encryption parameter validation
- **Encryption Tests**: Added 84 new tests covering all key types with encryption functionality
### Technical
- **PPKParser Options**: Enhanced parser to accept and process outputPassphrase parameter
- **Encryption Algorithm**: Uses AES-256-CTR cipher with bcrypt KDF for encrypted output
- **Test Suite**: Expanded test suite from ~200 to 284 tests with encryption validation
## [3.0.0] - 2025-06-19
### Added
- **Pure JavaScript Encryption**: Encrypt output keys with pure JS for ALL key types including Ed25519
- **Encrypt Flag Support**: Added `encrypt` option to `parseFromString()` and `parseFromFile()` functions
- **Universal Ed25519 Encryption**: Previously impossible Ed25519 encryption now supported via sshpk library
- **convertPPKWithEncryption()**: New dedicated function for PPK conversion with encryption
- **Comprehensive Encryption Testing**: All 28 test keys validated with encrypt flag functionality
- **OpenSSH Format Encryption**: Ed25519 and other keys encrypted in industry-standard OpenSSH format
- **PKCS#8 Fallback**: RSA/DSA/ECDSA keys support both OpenSSH and PKCS#8 encrypted formats
### Enhanced
- **API Functions**: `parseFromString()` and `parseFromFile()` now accept options parameter with encrypt flag
- **Error Validation**: Proper validation that `outputPassphrase` is required when `encrypt: true`
- **Decryption Testing**: All encrypted outputs verified to decrypt correctly with proper passphrases
- **Documentation**: Complete README update with encryption examples and API reference
- **Dependencies**: Added sshpk for universal SSH key encryption support
### Technical
- **sshpk Integration**: Pure JavaScript SSH key encryption library for Ed25519 support
- **Hybrid Approach**: sshpk primary with Node.js crypto fallback for maximum compatibility
- **Test Coverage**: 19 total tests including comprehensive encrypt flag validation
- **Backward Compatibility**: All existing code continues to work unchanged
## [2.0.0] - 2025-06-19
### Added
- **Comprehensive Testing**: 200+ test cases covering all PPK variants and edge cases
- **Complete DSA OpenSSH Support**: Full OpenSSH format support for DSA keys
- **Enhanced Result Object**: Added `algorithm` and `comment` fields to parser results
- **Extended PPK Coverage**: Support for RSA 2048-bit in PPK v2, ECDSA P-384/P-521 in PPK v2
- **Edge Case Testing**: Special characters, Unicode, and long passphrases support
- **Format Consistency Validation**: Ensures PEM and OpenSSH outputs are equivalent
### Enhanced
- **MAC Verification**: Fixed passphrase handling for unencrypted keys
- **OpenSSH Format**: Complete support for DSA keys in OpenSSH format
- **Test Coverage**: 28 comprehensive test keys covering all possible PPK variants
- **Error Handling**: Improved MAC verification logic for better reliability
### Fixed
- DSA keys now properly convert to OpenSSH format (was falling back to PEM)
- Unencrypted keys handle unnecessary passphrases correctly
- MAC verification uses correct passphrase for unencrypted keys (empty string)
### Testing
- **PPK v2 Coverage**: RSA (1024/2048), DSA (1024), ECDSA (P-256/P-384/P-521), Ed25519
- **PPK v3 Coverage**: RSA (2048/4096), DSA (1024), ECDSA (P-256/P-384/P-521), Ed25519
- **Encryption Coverage**: Both unencrypted and AES-256-CBC encrypted variants
- **Passphrase Testing**: Standard, special characters, Unicode, 100+ character lengths
- **Format Validation**: Both PEM and OpenSSH output formats thoroughly tested
### Breaking Changes
- `PPKParseResult` now includes `algorithm` and `comment` fields (additive, non-breaking)
- All DSA keys now support OpenSSH format (enhancement, backward compatible)
## [1.3.0] - 2024-12-19
### Added
- OpenSSH output format support for better ssh2-streams compatibility
- Configurable output format via `outputFormat` option (pem/openssh)
- Comprehensive OpenSSH private key format support for RSA and ECDSA
### Fixed
- PPK v3 unencrypted key MAC verification (critical bugfix)
- Proper MAC key derivation for unencrypted PPK v3 files
- Test coverage for MAC verification and output format options
### Changed
- Enhanced PPKParser constructor with outputFormat option
- Improved backward compatibility (PEM remains default)
- Updated documentation with OpenSSH format examples
### Removed
- Unnecessary development documentation files
## [1.2.3] - 2024-12-16
### Added
- Interactive passphrase prompting in CLI for encrypted PPK files
- Hidden input for passphrase entry (no echo to terminal)
- Automatic detection when passphrase is required
- Enhanced CLI help text with interactive mode documentation
### Changed
- CLI now automatically prompts for passphrases when encountering encrypted files (if no -p flag provided)
- Updated README with interactive mode examples and usage patterns
- Improved user experience for encrypted PPK file conversion
### Technical Details
- Pure JavaScript implementation using Node.js stdin raw mode
- Maintains full backward compatibility with existing -p flag
- No additional dependencies required
- Graceful error handling for Ctrl+C and other input scenarios
## [1.2.0] - 2024-12-16
### Added
- Complete PPK v3 support with Argon2id encryption
- Universal browser and Node.js compatibility via hash-wasm integration
- Production-ready PPK v3 file parsing for SSH connections
### Changed
- Replaced custom Argon2 implementation with proven hash-wasm library
- Improved error handling and debugging information
- Enhanced MAC verification for PPK v3 files
### Fixed
- PPK v3 MAC verification now works correctly with HMAC-SHA-256
- Argon2id key derivation produces correct output for PuTTY compatibility
- PPK v3 files with encrypted keys now decrypt properly for SSH use
### Technical Details
- Integrated hash-wasm (~11KB) for WebAssembly-based Argon2 implementation
- Fixed MAC calculation to use algorithm + encryption + comment + keys format
- Maintained full backward compatibility with PPK v2 files
- Added comprehensive test coverage for PPK v3 workflows
## [1.1.6] - 2024-11-06
### Fixed
- Resolved "Cannot read properties of undefined (reading '0')" crash when parsing PPK v3 files
- Simplified Argon2 implementation to prevent memory access errors
- PPK v3 files no longer crash the parser
### Known Issues
- PPK v3 full support still in development due to complex Argon2 requirements
- PPK v3 files may still fail MAC verification (decryption needs correct Argon2)
- PPK v2 files work perfectly
### Notes
- This release resolves the original crash reported by users
- Full PPK v3 support requires a complete Argon2 implementation matching PuTTY's exact algorithm
## [1.1.5] - 2024-11-06
### Fixed
- Fixed "Cannot read properties of undefined" errors in PPK v3 Argon2 processing
- Improved Argon2 memory management and reference indexing
- Added safety checks to prevent accessing uninitialized memory blocks
- Resolved variable scoping issue in error handling
- PPK v3 files now parse without crashes (MAC verification needs refinement)
### Known Issues
- PPK v3 MAC verification may fail due to simplified Argon2 implementation
- Working on full Argon2 specification compliance in next release
## [1.1.4] - 2024-11-06
### Fixed
- Fixed null reference errors in base64 regex match operations
- Added better validation for empty or missing key data sections
- Enhanced error reporting with detailed debugging information for troubleshooting
- Fixed potential crashes when PPK files have malformed base64 data
## [1.1.3] - 2024-11-06
### Fixed
- Fixed "Cannot read properties of undefined" errors in PPK parsing
- Added defensive programming for all split() operations to handle malformed PPK files
- Improved error handling for edge cases in PPK file structure parsing
## [1.1.2] - 2024-11-06
### Fixed
- Fixed PPK version parsing bug that caused "Unsupported PPK version: NaN" errors
- Improved regex pattern for parsing PPK v2 and v3 file headers
## [1.1.1] - 2024-11-06
### Fixed
- Fixed README.md formatting issue with missing code block closing tag
- Corrected markdown rendering for Requirements section
## [1.1.0] - 2024-11-06
### Added
- Zero dependencies: Removed all external dependencies including argon2-browser
- Built-in pure JavaScript Argon2 implementation for PPK v3 support
- Universal compatibility: Now works in Node.js, browsers, VS Code extensions, and any JavaScript environment
- Enhanced browser and VS Code extension support without dependency conflicts
### Changed
- Replaced argon2-browser dependency with built-in Argon2 implementation
- Updated documentation to highlight zero-dependency architecture
- Enhanced universal compatibility messaging
## [1.0.0] - 2024-11-06
### Added
- Initial release of ppk-to-openssh library
- Support for PPK versions 2 and 3
- Support for all key types: RSA, DSA, ECDSA (P-256, P-384, P-521), Ed25519
- Encryption support with AES-256-CBC and Argon2 key derivation
- Comprehensive error handling with structured error codes
- TypeScript definitions for better developer experience
- Command-line interface for easy conversion
- Pure JavaScript implementation with no native dependencies
- Cross-platform compatibility (Linux, macOS, Windows)
- Full MAC verification for security
- Input validation and size limits
- Both CommonJS and ES Modules support
### Features
- `parseFromFile()` - Convert PPK files from filesystem
- `parseFromString()` - Convert PPK content from strings
- `PPKParser` class with configurable options
- `PPKError` class with detailed error information
- CLI tool with comprehensive options and help
- Support for encrypted and unencrypted keys
- SHA256 fingerprint generation
- Proper OpenSSH and PEM format output
### Security
- Input validation and sanitization
- Buffer bounds checking
- File size limits (configurable, default 1MB)
- MAC verification for key integrity
- Secure error handling without information leakage