10
votes

Mot de passe auto-entrant dans Sn.exe

Je dois créer un événement de poste pour effectuer les éléments suivants:

sn -i MyKey.pfx MyKeyContainerName
tlbimp $(ConfigurationName)\MyCom.tlb /out:$(ConfigurationName)\NETMyCom.dll /keycontainer:MyKeyContainerName
sn -d MyKeyContainerName


1 commentaires

Y a-t-il une raison pour laquelle vous ne pouvez pas utiliser la propre fonctionnalité de signature de clé de Visual Studio? (Vérifiez les propriétés du projet.)


7 Réponses :



2
votes

J'avais ce problème aujourd'hui, avec une dll C ++ que j'utilise dans une application ClickOnce C #.

I Configurez la signature de délai sur la DLL, puis utilisé un événement post-construction pour exécuter Sn comme SA:

ECHO <your-password-here> | sn.exe -R $(OutDir)$(TargetFileName) $(MSBuildProjectDirectory)<path-to-pfx-file>


6 commentaires

Une autre chose très importante à savoir que je ne me souviens que de rappeler seulement: si vous mettez cette commande dans un fichier de commandes et que votre mot de passe contient un symbole % , vous devez utiliser deux d'entre eux. Si votre mot de passe est Super% Cool% Guy , vous devez utiliser Super %% Cool %% guy dans le fichier de commandes seulement .


L'idée est géniale, mais ne fonctionne pas sur un fichier de lot. Sn.exe n'accepte pas la redirection de l'entrée de la console et se plaint à ce sujet comme ceci: L'entrée de la console peut ne pas être redirigée pour la saisie de mot de passe . Des idées Comment y parvenir dans un fichier de commandes?


Je n'ai pas eu de problème avec ça. Pouvez-vous poster votre contenu de fichier par lot? (Je l'ai fait quelques années et peut-être que la dernière Sn.exe ne le permet pas)


Voici mon GIST . Essayé de définir le mot de passe dans une variable et de le tuyer dans la commande sn , mais pas de chance :(


Cela peut être modifié dans la version ultérieure de Sn peut-être - j'ai essayé avec un tuyau sans fichier de commandes directement à partir de la console qu'elle n'a pas fonctionné non plus.


Tu as probablement raison. Cela a fonctionné sur un plus ancien Sn.exe et ils pensaient probablement que les intrants de la tuyauterie étaient un risque de sécurité.



2
votes

Je suis en train de rechercher cela pendant près de deux jours maintenant. J'ai essayé des versions plus anciennes de Sn.exe (retourner jusqu'à 2.0!), Mais je ne pouvais pas obtenir le mot de passe echo | Trick pour travailler.

À la fin, j'ai fait ceci: xxx

  • sendwait () envoie les touches de la fenêtre activée en cours. Puisque nous commençons sn.exe en utilisant démarrage-processus avec le modificateur -nonewwindow , notre fenêtre est déjà axée sur la fenêtre.
  • ~ est un caractère spécial, représentant le bouton ENTER. {ENTER} est également possible, mais c'est pour le bouton ENTER près du numpad sur votre clavier. Probablement ne fait aucune différence, mais je voulais juste être sûr.

    Source J'ai utilisé: https://technet.microsoft .com / fr-US / bibliothèque / ff731008.aspx

    Je n'avais pas besoin de Appactivate () à la fin à la fin à cause de -nonewwindow .

    mise à jour: fonctionne encore mieux avec -Wait argument!


1 commentaires

Même erreur que le tuyau standard CMD, l'entrée ne peut pas être redirigée



0
votes

J'avais besoin de cela pour être automatisé et trouvé cette question. Suivant Cette Réponse (merci à merci @thomas Rijsewijk) J'ai écrit ma version de celui-ci:

# Start the sn.exe process
Start-Process $SnExePath -ArgumentList "-i $PfxCertificatePath $LocalContainerName" -NoNewWindow
# Wait for the process to start
Start-Sleep 2
# This workaround allows to forward the password to the standard input
[void] [System.Reflection.Assembly]::LoadWithPartialName("'System.Windows.Forms")
[System.Windows.Forms.SendKeys]::SendWait("$($PfxCertificatePassword){ENTER}")
Start-Sleep 2
# This ENTER is to return from the sn.exe process
[System.Windows.Forms.SendKeys]::SendWait("{ENTER}")


0 commentaires

0
votes

Après une longue enquête, je peux exécuter Sn.ex pour divers environnements automatisés tels que Azure Devops. Mon code est ici: XXX


0 commentaires

6
votes

Malheureusement, aucun approché mentionné ici a fonctionné pour moi. Je dois enregistrer couple PFXS dans un conteneur Docker.

alors j'ai ré-développé le sn.exe -i code> commande en C # à l'aide de RsacryptoserviceProvider . La source et l'application sont sur GitHub dans Le Projet Sninstallpfx . P>

SNINSTALLPFX APP accepte une clé PFX et son mot de passe. Il calcule le nom du conteneur de clé (vs_key_ *) automatiquement (emprunté à partir du code source MSBUILD) et l'installe au nom de Nom fort csp. P>

Utilisation: p>

SnInstallPfx.exe <pfx_infile> <pfx_password>


3 commentaires

Merci pour ça! Le plus utile.


Génial, Thx pour les commentaires! J'avais mis à jour CMDLN Args pour l'application. Vous pouvez éventuellement passer le nom du conteneur


Vous êtes littéralement un sauveur de la vie.



0
votes

Utiliser WinapI Nous pouvons le faire donc:

Param(
    [string]  $Password ,
    [string] $CertFilePath 
)

function ExecuteCommand([string]$message)
{
    try{
    foreach ($char in [char[]]$message) {
    [void][WPIA.ConsoleUtils]::PostMessage($handle, [WPIA.ConsoleUtils]::WM_CHAR, [int]$char, 0) 
    }
    [void][WPIA.ConsoleUtils]::PostMessage($handle, [WPIA.ConsoleUtils]::WM_CHAR, 13, 0)
    Sleep 3
    }catch{
    }
}

Add-Type -Name ConsoleUtils -Namespace WPIA -MemberDefinition @'
[DllImport("user32.dll")]
public static extern int PostMessage(int hWnd, uint Msg, int wParam, int lParam);
public const int WM_CHAR = 0x0102;
'@

$Win32API = Add-Type -Name Funcs -Namespace Win32 -PassThru -MemberDefinition @'
    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindow(string lpClassName, IntPtr lpWindowName);

    [DllImport("user32.dll", SetLastError = true)]
    public static extern IntPtr FindWindow(IntPtr lpClassName, string lpWindowName);

    [DllImport("user32.dll", SetLastError = true)]
        public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className,  string  windowTitle);

    [DllImport("kernel32.dll")]
  public static extern uint GetLastError();
'@

[System.Reflection.Assembly]::Load("Microsoft.Build.Tasks.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
[System.Reflection.Assembly]::Load("Microsoft.Build.Utilities.v4.0, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")
$publish = New-Object Microsoft.Build.Tasks.ResolveKeySource
$publish.KeyFile=$CertFilePath
try
{
        $publish.Execute()
}
catch{
        $VsKey= [regex]::match($error[0].Exception,'VS_KEY_[A-F0-9]+').Value
        $VsKey =$VsKey -replace "`n|`r"
}
$quotedCertPath='"'+$CertFilePath+'"'
Write-Host 'VsKey='$VsKey

start cmd
$proc=Get-Process | Where-Object {$_.Name -like "*cmd*"}
$proc.MainWindowTitle
$handle = $proc.MainWindowHandle
'1:'+$handle
if($handle -eq 0){
    $handle=$Win32API::FindWindow([IntPtr]::Zero, 'C:\WINDOWS\system32\cmd.exe')
    '2:'+$handle
}   
if($handle -eq 0){
    $handle=$Win32API::FindWindow('C:\WINDOWS\system32\cmd.exe',       [IntPtr]::Zero)
    '3:'+$handle
}
if($handle -eq 0){
    $proc2 = Start-Process cmd.exe -PassThru
    $proc2
    Get-Process -id $proc2.Id
    Sleep 3;
    $handle = (Get-Process -id $proc2.Id).MainWindowHandle
    $handle
    $proc.MainWindowHandle
    $proc.Refresh()
    Sleep 3;
    $proc.MainWindowHandle
}


Write-Host 'Handle='$handle

ExecuteCommand 'echo Starting > d:\a\1\s\Authenticode\log.txt'  
$SnCommand=[string]::Format(".\sn.exe -i {0} {1}",$quotedCertPath,$VsKey)
ExecuteCommand $SnCommand
ExecuteCommand $Password


0 commentaires