devolutions-crypto 0.10.1

An abstraction layer for the cryptography used by Devolutions
Documentation
<!-- Mobile header -->
<header class="mobile-header">
  <button (click)="w3Open()">&#9776;</button>
  <span>Devolutions Crypto</span>
</header>

<div class="page-inner">

  <div class="page-heading">
    <fa-icon size="3x" [icon]="faKey"></fa-icon>
    <h1>Key Derivation</h1>
  </div>

  <div class="card">
    <div class="card-title">Derive Secret Key</div>
    <div class="card-body">
      <form [formGroup]="deriveForm" (ngSubmit)="derive()">

        <!-- Algorithm selector -->
        <div class="field">
          <label>Algorithm</label>
          <div style="display:flex;gap:1rem;margin-top:0.25rem;">
            <label style="display:flex;align-items:center;gap:0.4rem;cursor:pointer;">
              <input type="radio" name="algorithm" value="argon2"
                [checked]="algorithm === 'argon2'"
                (change)="setAlgorithm('argon2')">
              Argon2 (recommended)
            </label>
            <label style="display:flex;align-items:center;gap:0.4rem;cursor:pointer;">
              <input type="radio" name="algorithm" value="pbkdf2"
                [checked]="algorithm === 'pbkdf2'"
                (change)="setAlgorithm('pbkdf2')">
              PBKDF2
            </label>
          </div>
        </div>

        <!-- Password -->
        <div class="field">
          <label>Password</label>
          <input type="password" formControlName="password" required placeholder="Enter password to derive">
        </div>

        <!-- Argon2 parameters -->
        @if (algorithm === 'argon2') {
          <div class="field">
            <label>Memory (KiB) <span style="font-weight:normal;color:#888;">— default: 4096</span></label>
            <input type="number" formControlName="argon2Memory" min="8" placeholder="e.g. 4096">
          </div>
          <div class="field">
            <label>Iterations <span style="font-weight:normal;color:#888;">— default: 2</span></label>
            <input type="number" formControlName="argon2Iterations" min="1" placeholder="e.g. 2">
          </div>
          <div class="field">
            <label>Lanes (parallelism) <span style="font-weight:normal;color:#888;">— default: 1</span></label>
            <input type="number" formControlName="argon2Lanes" min="1" placeholder="e.g. 1">
          </div>
          <p style="font-size:0.85rem;color:#888;margin:0.25rem 0 0.75rem;">
            A random salt is generated automatically on each derivation and embedded in the output parameters.
          </p>
        }

        <!-- PBKDF2 parameters -->
        @if (algorithm === 'pbkdf2') {
          <div class="field">
            <label>Iterations <span style="font-weight:normal;color:#888;">— default: 600 000</span></label>
            <input type="number" formControlName="pbkdf2Iterations" min="1" placeholder="e.g. 600000">
          </div>
          <div class="field">
            <label>Salt <span style="font-weight:normal;color:#888;">— optional, leave blank to generate randomly</span></label>
            <input type="text" formControlName="pbkdf2Salt" placeholder="Custom salt (UTF-8 text)">
          </div>
        }

        <div class="field">
          <button type="submit" class="btn btn-primary">Derive</button>
        </div>

        <!-- Outputs -->
        <div class="field">
          <span class="result-label">Secret Key (base64)</span>
          <textarea rows="3" formControlName="secretKeyResult"
            placeholder="Derived secret key will appear here"></textarea>
        </div>
        <div class="field">
          <span class="result-label">Derivation Parameters (base64)</span>
          <textarea rows="3" formControlName="parametersResult"
            placeholder="Serialized derivation parameters — store these to re-derive the same key later"></textarea>
        </div>

      </form>
    </div>
  </div>

</div>