Update Generate-Token2Cert.ps1

This commit is contained in:
Token2
2026-06-10 08:36:23 +02:00
committed by GitHub
parent b4ba3c70b1
commit 2287847821
+53 -170
View File
@@ -1,179 +1,62 @@
# TOTP Token Inventory: Automate Token2 Classic OATH Token Activation in Microsoft Entra ID
<#
Generate-Token2Cert-51.ps1 (Windows PowerShell 5.1 compatible)
Generates a self-signed cert, exports the public .cer for Entra,
and converts the private key to private_key.pem using OpenSSL.
Auto-detects OpenSSL from PATH or Git for Windows.
#>
---
$subject = "CN=Token2 Inventory App"
$years = 2
$outFolder = (Get-Location).Path
$pfxPass = "TempPfx123!" # temporary, only used during conversion
## **πŸš€ Key Feature: Automatic Token Activation**
The **TOTP Token Inventory** app now supports **automatic activation** of Token2 Classic OATH tokens during CSV upload. When tokens are assigned to users in the CSV, the app will:
- Retrieve the **secret key** of each token.
- Calculate the **current OTP code** (for both SHA-1 and SHA-256).
- Send the code to **Microsoft Graph API** for activation.
Write-Host "Generating certificate..." -ForegroundColor Cyan
This **eliminates the need for separate bulk activation tools**, making deployment **faster and more efficient**.
$cert = New-SelfSignedCertificate `
-Subject $subject `
-CertStoreLocation "Cert:\CurrentUser\My" `
-KeyExportPolicy Exportable `
-KeySpec Signature `
-KeyAlgorithm RSA `
-KeyLength 2048 `
-Provider "Microsoft Enhanced RSA and AES Cryptographic Provider" `
-NotAfter (Get-Date).AddYears($years)
---
$cerPath = Join-Path $outFolder "token2_public.cer"
$pfxPath = Join-Path $outFolder "token2_temp.pfx"
$pemPath = Join-Path $outFolder "private_key.pem"
## **1. Overview**
The **TOTP Token Inventory** app is a **powerful, open-source PHP tool** designed to **automate the management and activation** of **Token2 Classic OATH hardware tokens** in Microsoft Entra ID (Azure AD). Unlike Microsoft’s official tools, this app offers:
- A **user-friendly web interface**.
- **Bulk operations** (CSV/JSON import).
- **Automatic token activation** during CSV upload.
- **Self-service activation** for end users.
- **SHA-1 and SHA-256 support**.
- **Detailed logging** for auditing.
# Public cert for Entra
Export-Certificate -Cert $cert -FilePath $cerPath | Out-Null
---
# Temporary PFX (contains the private key)
$secure = ConvertTo-SecureString -String $pfxPass -Force -AsPlainText
Export-PfxCertificate -Cert $cert -FilePath $pfxPath -Password $secure | Out-Null
## **2. Comparison: TOTP Token Inventory vs. Microsoft’s Official Tools**
# Locate OpenSSL
$openssl = $null
$cmd = Get-Command openssl -ErrorAction SilentlyContinue
if ($cmd) { $openssl = $cmd.Source }
if (-not $openssl) {
foreach ($p in @(
"C:\Program Files\Git\usr\bin\openssl.exe",
"C:\Program Files\Git\mingw64\bin\openssl.exe",
"C:\Program Files (x86)\Git\usr\bin\openssl.exe"
)) { if (Test-Path $p) { $openssl = $p; break } }
}
| Feature | Microsoft CSV Blade (Admin Center) | Microsoft Graph API | TOTP Token Inventory (PHP App) |
|-----------------------------|-----------------------------------|---------------------|--------------------------------|
| **Automatic Activation** | ❌ No | ❌ No | βœ… **Yes** (during CSV upload) |
| **Bulk Import** | βœ… Yes (CSV only) | βœ… Yes | βœ… **Yes** (CSV/JSON) |
| **Self-Service Activation** | ❌ No | βœ… Yes | βœ… **Yes** |
| **SHA-256 Support** | ❌ No | βœ… Yes | βœ… **Yes** |
| **User-Friendly UI** | βœ… Basic | ❌ No (API only) | βœ… **Full Web UI** |
| **Detailed Logging** | ❌ No | ❌ No | βœ… **Yes** |
| **No Scripting Required** | βœ… Yes | ❌ No | βœ… **Yes** |
| **Open-Source** | ❌ No | ❌ No | βœ… **Yes** |
| **Bundled Windows App** | ❌ No | ❌ No | βœ… **Yes** |
if ($openssl) {
Write-Host "Converting key to PEM using: $openssl" -ForegroundColor Cyan
& $openssl pkcs12 -in $pfxPath -nocerts -nodes -passin "pass:$pfxPass" -out $pemPath 2>$null
Remove-Item $pfxPath -Force
Write-Host "Private key PEM (for the app) : $pemPath" -ForegroundColor Green
} else {
Write-Host "OpenSSL not found. PFX left at: $pfxPath" -ForegroundColor Yellow
Write-Host "Convert it manually with:" -ForegroundColor Yellow
Write-Host " openssl pkcs12 -in `"$pfxPath`" -nocerts -nodes -passin pass:$pfxPass -out `"$pemPath`""
}
---
## **3. Why Choose TOTP Token Inventory?**
- **Automatic Activation**: The **only solution** that activates tokens during CSV import, eliminating manual steps.
- **User-Friendly**: No scripting required; accessible via a **web UI**.
- **Bulk Operations**: Import and assign **hundreds of tokens at once**.
- **Self-Service**: Users activate tokens **without admin intervention**.
- **SHA-256 Support**: Handles both **SHA-1 and SHA-256** tokens.
- **Open-Source**: Free to use, modify, and deploy.
- **Bundled App**: Run on **Windows without a server** using PHPDesktop.
---
## **4. Pre-Requisites**
- **Server**: Works on **any server with PHP 7.4+** (Linux/Windows).
- **Bundled App**: Also available as a **PHPDesktop-based Windows app** (no server required).
- **Microsoft Entra ID**:
- **Tenant ID**, **Client ID**, and **either a Client Secret or a Certificate** (from an App Registration with **Graph API permissions**).
- **Authentication method**: The app supports **two ways** to authenticate the App Registration:
- **Client Secret** – the original, simplest method.
- **Certificate** – a **certificate-based credential** (signed JWT client assertion). More secure, as no shared secret is stored, and recommended for production. See **Section 6.F**.
- **Required permissions**:
- `Policy.ReadWrite.AuthenticationMethod`
- `UserAuthenticationMethod.ReadWrite.All`
- `User.Read.All`
- `Directory.Read.All`
- **Admin consent** for the above permissions.
- **Token2 Classic Tokens**: **CSV file** with token details (serial number, secret key, UPN, etc.).
- **CSVs for factory-set seeds are provided by Token2** via the seed request procedure.
---
## **5. Supported Formats**
| Format | Use Case | Description |
|---------|-------------------------------------------|-------------------------------------------------------------------------------------------------|
| **CSV** | Bulk import with pre-assignment and **automatic activation** | Admins can **pre-assign tokens to users** in the CSV. The app **automatically activates** these tokens by calculating the OTP code and sending it to Graph API. **CSVs for factory-set seeds are provided by Token2**. |
| **JSON** | Self-service repository | Tokens are uploaded to a **shared repository**. Users activate them via **Security Info**. |
---
## **6. Step-by-Step Guide**
### **A. Initial Setup**
1. **Download and install**:
- Deploy on a **PHP server** or use the **bundled Windows app**.
2. **Enter credentials**:
- Provide your **Tenant ID** and **Client ID**.
- Choose an **Authentication method**: **Client Secret** or **Certificate** (see **Section 6.F** to set up a certificate).
3. **Verify permissions**:
- Ensure the app has the required **Graph API permissions** and admin consent.
### **B. Importing Tokens**
1. **Prepare your CSV**:
- Include columns: `upn`, `serial number`, `secret key`, `timeinterval`, `manufacturer`, `model`.
- **Pre-assign tokens** by including user UPNs. The app will **automatically activate** these tokens.
- **CSVs for factory-set seeds are provided by Token2** via the seed request procedure.
2. **Upload CSV/JSON**:
- Use the **web interface** to upload your file.
- The app **automatically converts CSV to JSON** for Graph API and **activates pre-assigned tokens**.
### **C. Assigning Tokens**
- **Search for users** and assign tokens via the **web UI**.
- **Bulk assignment**: Assign multiple tokens at once using the CSV pre-assignment feature.
### **D. Activating Tokens**
- **Automatic activation**: When tokens are pre-assigned in the CSV, the app **automatically activates them** by calculating the OTP code and sending it to Graph API.
- **User self-service**: Users activate tokens via the **web form** or their **Security Info page**.
- **Auto-generation**: The app can **auto-generate TOTP codes** from the secret key for activation.
### **E. Managing Tokens**
- **Unassign/Delete**: Remove tokens from users or delete them permanently.
- **Logs**: View detailed logs for all operations.
---
### **F. Certificate-Based Authentication (Optional)**
Instead of a **Client Secret**, you can authenticate the App Registration using a **certificate**. The app builds a **signed JWT client assertion** and sends it to Entra ID β€” no shared secret is stored on disk.
**What you need:**
- A **public certificate** (`.cer`) uploaded to your App Registration.
- The matching **private key in PEM format** (`-----BEGIN PRIVATE KEY-----`), readable by the PHP process.
- The certificate **thumbprint** (hex), shown by Entra ID after upload.
**1. Generate a certificate (Windows, PowerShell):**
Use the bundled helper script `Generate-Token2Cert.ps1` (PowerShell 7+) or `Generate-Token2Cert-51.ps1` (Windows PowerShell 5.1, uses OpenSSL):
```powershell
powershell -ExecutionPolicy Bypass -File .\Generate-Token2Cert.ps1
```
This produces:
- `token2_public.cer` – the **public certificate** to upload to Entra ID.
- `private_key.pem` – the **private key** for the app.
- A printed **thumbprint** to paste into the app.
> **Note:** If a **SafeNet / Thales token dialog** appears, it means a hardware-token provider is being used. The scripts force the **Microsoft software provider** (`-Provider "Microsoft Enhanced RSA and AES Cryptographic Provider"`) to avoid this. Hardware-token-stored keys cannot be exported to PEM and are not supported by this app.
Alternatively, generate everything in one step with **OpenSSL**:
```powershell
openssl req -x509 -newkey rsa:2048 -keyout private_key.pem -out token2_public.cer -days 730 -nodes -subj "/CN=Token2 Inventory App"
openssl x509 -in token2_public.cer -noout -fingerprint -sha1
```
**2. Upload the public certificate to Entra ID:**
- Go to **Azure Portal β†’ App registrations β†’ your app β†’ Certificates & secrets β†’ Certificates β†’ Upload certificate**.
- Upload `token2_public.cer`.
- Entra ID displays the **thumbprint** β€” confirm it matches the one printed by the script.
**3. Configure the app:**
- On the credentials screen (or **Settings**), set **Authentication method** to **Certificate**.
- **Private key file path**: full path to `private_key.pem` (e.g. `C:\token2\private_key.pem`).
- **Private key passphrase**: only if you created an **encrypted** PEM; otherwise leave blank.
- **Certificate thumbprint**: paste the hex thumbprint.
**4. Security notes:**
- Treat `private_key.pem` like a password β€” anyone with it can authenticate as your app.
- Store the key **outside the web root** when running on a web server.
- A **self-signed certificate is sufficient**, because Entra ID trusts it by explicit upload (not by a CA chain).
- Set a reminder before the certificate **expiry date** β€” token requests fail once it expires.
---
## **7. Best Practices**
- **Backup credentials**: Store your **Client Secret** or **private key (PEM)** securely.
- **Prefer certificates in production**: Certificate-based auth avoids storing a shared secret and is generally more secure than a Client Secret.
- **Test with a small batch**: Validate the workflow before bulk importing.
- **Monitor logs**: Use logs to audit operations and troubleshoot issues.
- **Keep permissions updated**: Ensure Graph API permissions are current.
---
## **8. Conclusion**
The **TOTP Token Inventory** app is the **only solution** that offers **automatic token activation** during CSV import, making it the **most efficient way** to deploy and manage **Token2 Classic OATH tokens** in Microsoft Entra ID. With its **user-friendly interface**, **bulk operations**, and **self-service activation**, it provides a **complete, scalable, and auditable** solution for organizations of all sizes.
**Say goodbye to manual activation processesβ€”TOTP Token Inventory automates everything.**
Write-Host ""
Write-Host "Public cert (upload to Entra) : $cerPath"
Write-Host "Thumbprint (paste into app) : $($cert.Thumbprint)" -ForegroundColor Yellow
Write-Host "Passphrase in app : leave blank"