I was wondering how if there were any current ways to import lastpass passwords to keepass/keepassx? I found the lastpass2keepass.py program, but it doesn't seem to work anymore (lastpass updated their csv fields?).
4 Answers
Well, doesn't seem like there were any, so I hacked together a quick php script to do it.
If anyone else needs to do it. Run this script, paste the exported csv in the textarea, and input the outputted csv file to keepass.
<?php
if (isset($_POST["submit"]))
{
//Loop through, build a multi array;
$parsedCSV = array();
//Columns (in order) to parse out.
$ColumnAssociation = array("%%name%%","%%username%%","%%password%%","%%url%%","%%extra%%"); //The xml strings to use for output, replace %%COLUMNNAME%% with COLUMNVALUE
$LastPassHeaders = array();
$inQuotes = false;
$quoteType = '';
$curColumn = 0;
//My epic parser, I know, deal with it (it wasn't meant to be modified)
$first = true;
$curLine = 0;
foreach (explode("\n",$_POST["csvinput"]) as $line)
{
if (empty($line)) //I do this instead of searching for \r\n, because linux just uses \n (I think :/)
continue;
$letters = str_split($line);
//print_r( $letters);
for ($i = 0; $i < count($letters); $i++)
{
/*if ($first) //get lastpass's headers (they are the first row
{
}*/
//Set inQuotes
if (!$inQuotes && $letters[$i] == "'" && ($i - 1 < 0 || $letters[$i - 1] != '\\')) //Not Inquotes, matching singlequote, not prefixed with escape character
{
$inQuotes = true;
$quoteType = "'";
continue;
}
else if (!$inQuotes && $letters[$i] == '"' && ($i - 1 < 0 || $letters[$i - 1] != '\\')) //Not Inquotes, matching doublequote, not prefixed with escape character
{
$inQuotes = true;
$quoteType = '"';
continue;
}
else if ($inQuotes && $letters[$i] == $quoteType && ($i - 1 < 0 || $letters[$i - 1] != '\\')) //Inquotes, is the endquote, and isn't prefixed with an escape character
{
$inQuotes = false;
$quoteType = '';
continue;
}
//Finished with quotes
if (!$inQuotes && $letters[$i] == ',' && ($i - 1 < 0 || $letters[$i - 1] != '\\'))
{
$curColumn++;
continue;
/*if ($curColumn > count($ColumnAssociation))
throw new Exception("TO MANY COLUMNS FTW");*/
}
//Well, because lastpass doesn't incapsulate their stuff, I guess I'll just wing it
if (!$first) //If not headers, parse normally
{
if (!isset($parsedCSV[$curLine][$LastPassHeaders[$curColumn]]))
$parsedCSV[$curLine][$LastPassHeaders[$curColumn]] = "";
$parsedCSV[$curLine][$LastPassHeaders[$curColumn]] .= $letters[$i];
}
else if ($first)
{
if (!isset($LastPassHeaders[$curColumn]))
$LastPassHeaders[$curColumn] = '';
$LastPassHeaders[$curColumn] .= $letters[$i];
}
}
if ($inQuotes)
throw new Exception('Error, Unexpected end of line (Check quotes)');
$curColumn = 0;
if ($first)
$first = false;
else
$curLine++; //Put this here so it only adds to the column number if the current row wasn't the first row (header)
}
//print_r($parsedCSV);
//print_r($LastPassHeaders);
$output = '"Account","Login Name","Password","Web Site","Comments"'."\r\n";
//Alright, now reprint in xml format
foreach ($parsedCSV as $row)
{
//print_r($row);
//Don't output Generated passwords?
if (isset($_POST["rgp"]) && $_POST["rgp"] && stristr($row['name'],'Generated Password for '))
continue;
//$output .= "<pwentry>\r\n";
foreach ($ColumnAssociation as $xmlstring) //first loop through each xml string
{
$nxml = $xmlstring;
foreach ($LastPassHeaders as $name) //then loop through each possible variable in the string
if (isset($row[$name])) //because if a column is empty, it isn't even set in the array
$nxml = str_replace('%%'.$name.'%%',$row[$name],$nxml); //then replace found variables
else
$nxml = str_replace('%%'.$name.'%%','',$nxml); //just because it isn't set, doesn't mean it isn't a real variable, hide it
$output .= '"'.$nxml.'",';
}
$output = substr($output,0,-1); //remove end ,
//$output .= "</pwentry>\r\n";
$output .= "\r\n";
}
header("Content-type:application/csv");
// It will be called lastpass-export.csv
header("Content-Disposition:attachment;filename=lastpass-export.csv");
echo $output;
}
else
{
?>
<html>
<body>
<form action="<?php echo $_SERVER["PHP_SELF"]; ?>" method="POST">
<textarea name="csvinput" cols="100" rows="20"></textarea><BR />
Remove Generated Passwords? <input type="checkbox" name="rgp"/ ><BR/>
<input type="submit" name="submit" value="Generate" />
</form>
Created By Mazzzzz
</body>
</html>
<?php
}
?>
- 469
As of 19/Dec/2012 the https://github.com/anirudhjoshi/lastpass2keepass script does indeed work.
Just export your LastPass data in CSV format then run it through the python script, then import it into KeePass (I used KeePassX)
- 62,374
- 263
Export your LastPass passwords to a CSV file. Click on LastPass browser icon, go to Tools > Export to > LastPass CSV file.
Next, in KeePass go to File > Import > Generic CSV file. This should import the passwords.
- 62,374
As of KeePassX 2.0.2 and lastpass2keepass of Oct 23, 2014, it's not possible to import neither XML nor CSV into KeePassX.
There are just no such button (only kdb import provided).
Any known workarounds?
Yes, it's KeePassXC - drop the conversion step and go straight to CSV import (check 1st line as field names).
- 321