mirror of
https://github.com/moparisthebest/keepass2android
synced 2025-01-09 04:28:05 -05:00
first version of MasterPasswordAlgorithm ported to .net
This commit is contained in:
parent
4fae385cc1
commit
2e56a007fc
72
src/MPTest/MPTest.csproj
Normal file
72
src/MPTest/MPTest.csproj
Normal file
@ -0,0 +1,72 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{96A3EA5A-7024-479F-A5B1-06654D0867A3}</ProjectGuid>
|
||||
<OutputType>Exe</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MPTest</RootNamespace>
|
||||
<AssemblyName>MPTest</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<Prefer32Bit>false</Prefer32Bit>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<SpecificVersion>False</SpecificVersion>
|
||||
<HintPath>..\..\..\..\..\..\..\Program Files (x86)\Microsoft Visual Studio 11.0\Common7\IDE\PublicAssemblies\Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Main.cs" />
|
||||
<Compile Include="MpTest.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="app.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\MasterPassword\MasterPassword.csproj">
|
||||
<Project>{2f7cb5b4-ac2a-4790-b0f3-42e6c9a060d5}</Project>
|
||||
<Name>MasterPassword</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
16
src/MPTest/Main.cs
Normal file
16
src/MPTest/Main.cs
Normal file
@ -0,0 +1,16 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MPTest
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static int Main()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
69
src/MPTest/MpTest.cs
Normal file
69
src/MPTest/MpTest.cs
Normal file
@ -0,0 +1,69 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using MasterPassword;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
namespace MPTest
|
||||
{
|
||||
|
||||
[TestClass()]
|
||||
public class MpAlgorithmTests
|
||||
{
|
||||
private static byte[] HashHMAC(byte[] key, byte[] message)
|
||||
{
|
||||
var hash = new HMACSHA256(key);
|
||||
return hash.ComputeHash(message);
|
||||
}
|
||||
|
||||
[TestMethod()]
|
||||
public void GenerateKeyTest()
|
||||
{
|
||||
sbyte[] expectedRes =
|
||||
{
|
||||
-103, 59, -64, -27, 39, -62, 10, -76, -24, -28, -111, -75, 13, -128, -80, -101, 39, 41, -98, -22,
|
||||
-42, 61, -75, 38, -107, -40, 111, 61, 108, 63, 60, 82, 92, -39, 72, 14, 14, -26, 93, 67, 83, 25, -32, 5, 32, 102,
|
||||
-126, 24, 15, 65, 9, 17, 0, 123, 91, 105, -46, -99, -64, 123, -12, 80, -37, -77
|
||||
};
|
||||
var result = MpAlgorithm.GetKeyForPassword("u", "test");
|
||||
|
||||
Assert.IsTrue(expectedRes.SequenceEqual(result));
|
||||
|
||||
}
|
||||
[TestMethod]
|
||||
public void GenerateContentTest()
|
||||
{
|
||||
var key = MpAlgorithm.GetKeyForPassword("u", "test");
|
||||
string password = MpAlgorithm.GenerateContent("Long Password", "strn", key, 1, HashHMAC);
|
||||
Assert.AreEqual("LapdKebv2_Tele", password);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GenerateContentWithUmlautsTest()
|
||||
{
|
||||
var key = MpAlgorithm.GetKeyForPassword("uÜ", "testÖ");
|
||||
string password = MpAlgorithm.GenerateContent("Long Password", "strnÄ", key, 1, HashHMAC);
|
||||
Assert.AreEqual("YepiHedo1*Kada", password);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GenerateContentWithUmlautsAndCounterTest()
|
||||
{
|
||||
var key = MpAlgorithm.GetKeyForPassword("uÜ", "testÖ");
|
||||
string password = MpAlgorithm.GenerateContent("Long Password", "strnÄ", key, 42, HashHMAC);
|
||||
Assert.AreEqual("Gasc3!YeluMoqb", password);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void GetKeyWithUmlautsTest()
|
||||
{
|
||||
var key = MpAlgorithm.GetKeyForPassword("uÜ", "testÖ");
|
||||
sbyte[] expected =
|
||||
{
|
||||
-53, -69, -89, 48, 122, 56, 34, 13, -70, -103, 102, 90, -96, -75, 45, 68, 43, 67, 97, 60, 84, -90, 98, -95, -2, -2, 99, -60, -121, -2, -26, -45, 53, -31, 47, 0, -46, -97, 77, -41, 63, -15, -30, 60, 4, -120, 32, 122, -94, 42, 122, -103, -61, -115, 75, -123, -15, 47, 61, -100, -119, 115, 118, 82
|
||||
};
|
||||
Assert.IsTrue(expected.SequenceEqual(key));
|
||||
}
|
||||
}
|
||||
}
|
36
src/MPTest/Properties/AssemblyInfo.cs
Normal file
36
src/MPTest/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,36 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über die folgenden
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die mit einer Assembly verknüpft sind.
|
||||
[assembly: AssemblyTitle("MPTest")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("MPTest")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Durch Festlegen von ComVisible auf "false" werden die Typen in dieser Assembly unsichtbar
|
||||
// für COM-Komponenten. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
// COM zugreifen müssen, legen Sie das ComVisible-Attribut für diesen Typ auf "true" fest.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// Die folgende GUID bestimmt die ID der Typbibliothek, wenn dieses Projekt für COM verfügbar gemacht wird
|
||||
[assembly: Guid("5fbae881-f9e4-4aa1-adff-4721cad61250")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||
// übernehmen, indem Sie "*" eingeben:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
3
src/MPTest/app.config
Normal file
3
src/MPTest/app.config
Normal file
@ -0,0 +1,3 @@
|
||||
<?xml version="1.0"?>
|
||||
<configuration>
|
||||
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/></startup></configuration>
|
57
src/MasterPassword/MasterPassword.csproj
Normal file
57
src/MasterPassword/MasterPassword.csproj
Normal file
@ -0,0 +1,57 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{2F7CB5B4-AC2A-4790-B0F3-42E6C9A060D5}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>MasterPassword</RootNamespace>
|
||||
<AssemblyName>MasterPassword</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MPAlgorithm.cs" />
|
||||
<Compile Include="MpPasswordPlistData.cs" />
|
||||
<Compile Include="PList.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="CryptSharp">
|
||||
<HintPath>..\packages\CryptSharpOfficial.2.0.0.0\lib\CryptSharp.dll</HintPath>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
120
src/MasterPassword/MpAlgorithm.cs
Normal file
120
src/MasterPassword/MpAlgorithm.cs
Normal file
@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using CryptSharp.Utility;
|
||||
using MasterPassword.Data;
|
||||
|
||||
|
||||
namespace MasterPassword
|
||||
{
|
||||
public partial class MpAlgorithm
|
||||
{
|
||||
|
||||
static readonly PList PlistData = new PList(plist);
|
||||
private const int MP_N = 32768;
|
||||
private const int MP_r = 8;
|
||||
private const int MP_p = 2;
|
||||
private const int MP_dkLen = 64;
|
||||
|
||||
static sbyte[] ToSignedByteArray(byte[] unsigned)
|
||||
{
|
||||
sbyte[] signed = new sbyte[unsigned.Length];
|
||||
Buffer.BlockCopy(unsigned, 0, signed, 0, unsigned.Length);
|
||||
return signed;
|
||||
}
|
||||
static byte[] ToUnsignedByteArray(sbyte[] signed)
|
||||
{
|
||||
byte[] unsigned = new byte[signed.Length];
|
||||
Buffer.BlockCopy(signed, 0, unsigned, 0, signed.Length);
|
||||
return unsigned;
|
||||
}
|
||||
|
||||
public static byte[] GetKeyForPassword(string user, string password)
|
||||
{
|
||||
var salt = Combine(Encoding.UTF8.GetBytes("com.lyndir.masterpassword"),
|
||||
IntAsByteArray(user.Length),
|
||||
Encoding.UTF8.GetBytes(user));
|
||||
var ssalt = ToSignedByteArray(salt);
|
||||
var spwd = ToSignedByteArray(Encoding.UTF8.GetBytes(password));
|
||||
var key = SCrypt.ComputeDerivedKey(Encoding.UTF8.GetBytes(password),
|
||||
salt,
|
||||
MP_N,
|
||||
MP_r,
|
||||
MP_p,null, MP_dkLen);
|
||||
|
||||
sbyte[] signed = ToSignedByteArray(key);
|
||||
return signed;
|
||||
}
|
||||
|
||||
|
||||
static byte[] Combine(params byte[][] arrays)
|
||||
{
|
||||
byte[] ret = new byte[arrays.Sum(x => x.Length)];
|
||||
int offset = 0;
|
||||
foreach (byte[] data in arrays)
|
||||
{
|
||||
Buffer.BlockCopy(data, 0, ret, offset, data.Length);
|
||||
offset += data.Length;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
static byte[] IntAsByteArray(int intValue)
|
||||
{
|
||||
byte[] intBytes = BitConverter.GetBytes(intValue);
|
||||
if (BitConverter.IsLittleEndian)
|
||||
Array.Reverse(intBytes);
|
||||
return intBytes;
|
||||
}
|
||||
|
||||
public static String GenerateContent(string elementType, string siteName, sbyte[] key, int counter, Func<byte[], byte[], byte[]> hmacFunc)
|
||||
{
|
||||
if (counter == 0)
|
||||
{
|
||||
throw new Exception("counter==0 not support in .net. ");
|
||||
//TODO: what does this line do in Java?
|
||||
//counter = (int) (System.currentTimeMillis() / (300 * 1000)) * 300;
|
||||
}
|
||||
|
||||
|
||||
byte[] nameLengthBytes = IntAsByteArray(siteName.Length);
|
||||
byte[] counterBytes =IntAsByteArray(counter);
|
||||
|
||||
sbyte[] seed = ToSignedByteArray(hmacFunc( ToUnsignedByteArray(key), Combine( Encoding.UTF8.GetBytes("com.lyndir.masterpassword"), //
|
||||
nameLengthBytes, //
|
||||
Encoding.UTF8.GetBytes(siteName), //
|
||||
counterBytes ) ) );
|
||||
//logger.trc( "seed is: %s", CryptUtils.encodeBase64( seed ) );
|
||||
|
||||
//Preconditions.checkState( seed.length > 0 );
|
||||
int templateIndex = seed[0] & 0xFF; // Mask the integer's sign.
|
||||
//MPTemplate template = templates.getTemplateForTypeAtRollingIndex( type, templateIndex );
|
||||
//MPTemplate template = null;
|
||||
|
||||
|
||||
|
||||
var templatesLongPwd = PlistData["MPElementGeneratedEntity"]["Long Password"];
|
||||
string template = templatesLongPwd[templateIndex%templatesLongPwd.Count];
|
||||
//logger.trc( "type: %s, template: %s", type, template );
|
||||
|
||||
StringBuilder password = new StringBuilder( template.Length );
|
||||
for (int i = 0; i < template.Length; ++i) {
|
||||
int characterIndex = seed[i + 1] & 0xFF; // Mask the integer's sign.
|
||||
|
||||
char c = template[i];
|
||||
|
||||
PList listOfCharacterSets = PlistData["MPCharacterClasses"];
|
||||
var listOfCharacters = listOfCharacterSets.Single(kvp => { return kvp.Key == c.ToString(); }).Value;
|
||||
|
||||
char passwordCharacter = listOfCharacters[characterIndex % listOfCharacters.Length];
|
||||
/*logger.trc( "class: %s, index: %d, byte: 0x%02X, chosen password character: %s", characterClass, characterIndex, seed[i + 1],
|
||||
passwordCharacter );
|
||||
*/
|
||||
password.Append(passwordCharacter);
|
||||
}
|
||||
|
||||
return password.ToString();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
90
src/MasterPassword/MpPasswordPlistData.cs
Normal file
90
src/MasterPassword/MpPasswordPlistData.cs
Normal file
@ -0,0 +1,90 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MasterPassword
|
||||
{
|
||||
public partial class MpAlgorithm
|
||||
{
|
||||
private const string plist = @"<?xml version=""1.0"" encoding=""UTF-8""?>
|
||||
<plist version=""1.0"">
|
||||
<dict>
|
||||
<key>MPElementGeneratedEntity</key>
|
||||
<dict>
|
||||
<key>Maximum Security Password</key>
|
||||
<array>
|
||||
<string>anoxxxxxxxxxxxxxxxxx</string>
|
||||
<string>axxxxxxxxxxxxxxxxxno</string>
|
||||
</array>
|
||||
<key>Long Password</key>
|
||||
<array>
|
||||
<string>CvcvnoCvcvCvcv</string>
|
||||
<string>CvcvCvcvnoCvcv</string>
|
||||
<string>CvcvCvcvCvcvno</string>
|
||||
<string>CvccnoCvcvCvcv</string>
|
||||
<string>CvccCvcvnoCvcv</string>
|
||||
<string>CvccCvcvCvcvno</string>
|
||||
<string>CvcvnoCvccCvcv</string>
|
||||
<string>CvcvCvccnoCvcv</string>
|
||||
<string>CvcvCvccCvcvno</string>
|
||||
<string>CvcvnoCvcvCvcc</string>
|
||||
<string>CvcvCvcvnoCvcc</string>
|
||||
<string>CvcvCvcvCvccno</string>
|
||||
<string>CvccnoCvccCvcv</string>
|
||||
<string>CvccCvccnoCvcv</string>
|
||||
<string>CvccCvccCvcvno</string>
|
||||
<string>CvcvnoCvccCvcc</string>
|
||||
<string>CvcvCvccnoCvcc</string>
|
||||
<string>CvcvCvccCvccno</string>
|
||||
<string>CvccnoCvcvCvcc</string>
|
||||
<string>CvccCvcvnoCvcc</string>
|
||||
<string>CvccCvcvCvccno</string>
|
||||
</array>
|
||||
<key>Medium Password</key>
|
||||
<array>
|
||||
<string>CvcnoCvc</string>
|
||||
<string>CvcCvcno</string>
|
||||
</array>
|
||||
<key>Basic Password</key>
|
||||
<array>
|
||||
<string>aaanaaan</string>
|
||||
<string>aannaaan</string>
|
||||
<string>aaannaaa</string>
|
||||
</array>
|
||||
<key>Short Password</key>
|
||||
<array>
|
||||
<string>Cvcn</string>
|
||||
</array>
|
||||
<key>PIN</key>
|
||||
<array>
|
||||
<string>nnnn</string>
|
||||
</array>
|
||||
</dict>
|
||||
<key>MPCharacterClasses</key>
|
||||
<dict>
|
||||
<key>V</key>
|
||||
<string>AEIOU</string>
|
||||
<key>C</key>
|
||||
<string>BCDFGHJKLMNPQRSTVWXYZ</string>
|
||||
<key>v</key>
|
||||
<string>aeiou</string>
|
||||
<key>c</key>
|
||||
<string>bcdfghjklmnpqrstvwxyz</string>
|
||||
<key>A</key>
|
||||
<string>AEIOUBCDFGHJKLMNPQRSTVWXYZ</string>
|
||||
<key>a</key>
|
||||
<string>AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz</string>
|
||||
<key>n</key>
|
||||
<string>0123456789</string>
|
||||
<key>o</key>
|
||||
<string>@&%?,=[]_:-+*$#!'^~;()/.</string>
|
||||
<key>x</key>
|
||||
<string>AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()</string>
|
||||
</dict>
|
||||
</dict>
|
||||
</plist>
|
||||
";
|
||||
}
|
||||
}
|
83
src/MasterPassword/PList.cs
Normal file
83
src/MasterPassword/PList.cs
Normal file
@ -0,0 +1,83 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using System.Xml.Linq;
|
||||
|
||||
namespace MasterPassword.Data
|
||||
{
|
||||
public class PList : Dictionary<string, dynamic>
|
||||
{
|
||||
public PList()
|
||||
{
|
||||
}
|
||||
|
||||
public PList(string data)
|
||||
{
|
||||
Read(data);
|
||||
}
|
||||
|
||||
public void Read(string data)
|
||||
{
|
||||
Clear();
|
||||
|
||||
//XDocument doc = XDocument.Load(file);
|
||||
XDocument doc = XDocument.Load(XmlReader.Create(new StringReader(data)));
|
||||
XElement plist = doc.Element("plist");
|
||||
XElement dict = plist.Element("dict");
|
||||
|
||||
var dictElements = dict.Elements();
|
||||
Parse(this, dictElements);
|
||||
}
|
||||
|
||||
private void Parse(PList dict, IEnumerable<XElement> elements)
|
||||
{
|
||||
for (int i = 0; i < elements.Count(); i += 2)
|
||||
{
|
||||
XElement key = elements.ElementAt(i);
|
||||
XElement val = elements.ElementAt(i + 1);
|
||||
|
||||
dict[key.Value] = ParseValue(val);
|
||||
}
|
||||
}
|
||||
|
||||
private List<dynamic> ParseArray(IEnumerable<XElement> elements)
|
||||
{
|
||||
List<dynamic> list = new List<dynamic>();
|
||||
foreach (XElement e in elements)
|
||||
{
|
||||
dynamic one = ParseValue(e);
|
||||
list.Add(one);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
private dynamic ParseValue(XElement val)
|
||||
{
|
||||
switch (val.Name.ToString())
|
||||
{
|
||||
case "string":
|
||||
return val.Value;
|
||||
case "integer":
|
||||
return int.Parse(val.Value);
|
||||
case "real":
|
||||
return float.Parse(val.Value);
|
||||
case "true":
|
||||
return true;
|
||||
case "false":
|
||||
return false;
|
||||
case "dict":
|
||||
PList plist = new PList();
|
||||
Parse(plist, val.Elements());
|
||||
return plist;
|
||||
case "array":
|
||||
List<dynamic> list = ParseArray(val.Elements());
|
||||
return list;
|
||||
default:
|
||||
throw new ArgumentException("Unsupported");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
30
src/MasterPassword/Properties/AssemblyInfo.cs
Normal file
30
src/MasterPassword/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,30 @@
|
||||
using System.Resources;
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Allgemeine Informationen über eine Assembly werden über folgende
|
||||
// Attribute gesteuert. Ändern Sie diese Attributwerte, um die Informationen zu ändern,
|
||||
// die einer Assembly zugeordnet sind.
|
||||
[assembly: AssemblyTitle("MasterPassword")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("MasterPassword")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2014")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
[assembly: NeutralResourcesLanguage("de")]
|
||||
|
||||
// Versionsinformationen für eine Assembly bestehen aus den folgenden vier Werten:
|
||||
//
|
||||
// Hauptversion
|
||||
// Nebenversion
|
||||
// Buildnummer
|
||||
// Revision
|
||||
//
|
||||
// Sie können alle Werte angeben oder die standardmäßigen Build- und Revisionsnummern
|
||||
// durch Einsatz von '*', wie in nachfolgendem Beispiel:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
4
src/MasterPassword/packages.config
Normal file
4
src/MasterPassword/packages.config
Normal file
@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="CryptSharpOfficial" version="2.0.0.0" targetFramework="portable-win+net45+MonoAndroid10+MonoTouch10" />
|
||||
</packages>
|
Loading…
Reference in New Issue
Block a user