Using Crypto++ library with Windows Phone 8
This article explains how to use Crypto++, a C++ library that offers various cryptographic schemes on the Windows Phone platform.
Windows Phone 8
Contents |
Introduction
There are several C# APIs which can be used by Windows Phone apps to encrypt and decrypt data. If you wish to use C++ instead, one alternative is the Crypto++ library by Wei Dai. Crypto++ implements a large number of cryptographic algorithms, provides support for different compilers such as GCC, C++, and MSVC, and has a permissive license.
This article provides a code example which uses the Crypto++ library to encrypt and decrypt a String. The Crypto++ library can be used in many other ways, for example, to encrypt/decrypt files (irrespective of their formats).
Prerequisites
To use the Crypto++ library within our Windows Phone project, we first need to build it. You can download the library project from the Crypto++ homepage.
- Go to the Download section on Crypto++
- Download Crypto++ 5.6.2
Building the Crypto++ library project
- Unzip the downloaded folder (cryptopp562)
- Locate the Visual Studio solution file cryptest.sln and open it with VS2012 for Windows Phone
- Our solution involves four projects.[1]: cryptest, cryptlib, cryptopp and dlltest.
- Since Crypto++ is built with an older version of Visual Studio, Visual Studio will ask to convert all four projects to the current version.
- All four projects have different usage. We want to build a static library (.lib file), so we only need to build the Cryptlib project.
- You need to set some important project properties. To do this, right-click on the Cryptlib project and go to its properties. Update them as shown in the following screenshots.
To summarize the above properties:
- Configuration Properties->General->Platform Toolset - Visual Studio 2012(v110)
- Configuration Properties->General->Configuration Type - Static library(.lib)
- Configuration Properties->C/C++->Code generation->Runtime library - Multi-threaded Debug (/MTd) (for Debug Config & Multi-threaded DLL (/MD) for Release Config)
Building for different configurations
To build the Cryptlib project for the emulator, select the Win32 target. To build the project for a device, select the ARM target.
Since the ARM target isn't in the platforms list by default, you must add it as follows:
- Right-click Project->Properties->Configuration Manager (upper right side of the window)
- Select Active solution platform (dropdown list) ->New
- Choose ARM (as new platform) and leave 'Copy Settings from' empty
This will add the ARM platform to the project.
Resolving problems that arise while building the library project
For ARM(device build) configuration :
When building the Cryptlib project for the first time, several build errors come up, shown in the image below:
To resolve these errors, navigate to the config.h header file in the Cryptlib project (Cryptlib->Header Files) and add the following macros at the top of the file:
- #define CRYPTOPP_DISABLE_ASM
This disables the assembly code which is present in the Cryptopp library project.
- #define CRYPTOPP_DISABLE_SSE2
The SSE2 instruction set is available only for x86 type systems, thereby its necessary to disable it for non x86 systems which in our case is Windows Phone device which has the ARM architecture.
Recompiling the project after the above change should resolve the first set of errors.
Then another set of errors appears: __emulu undefined in two cpp files: Integer.cpp & VMAC.cpp. To resolve these, navigate to the error location in the files and make the following changes:
- In Integer.cpp replace the following macro:
#if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER)
//#define MultiplyWords(p, a, b) p = __emulu(a, b);
#define MultiplyWords(p, a, b) p = (dword)a*b;
#else
#define MultiplyWords(p, a, b) p = (dword)a*b;
- In VMAC.cpp replace the following macro:
#if _MSC_VER >= 1400 && !defined(__INTEL_COMPILER)
//#define MUL32(a, b) __emulu(word32(a), word32(b))
#define MUL32(a, b) ((word64)((word32)(a)) * (word32)(b))
#else
#define MUL32(a, b) ((word64)((word32)(a)) * (word32)(b))
For Win32(emulator build) configuration : No changes required
End Result
After performing the above steps, compiling the Cryptlib project will result in the creation of a Cryptlib.lib static library at something like the following location:
G:\Users\username\Downloads\cryptopp\ARM(or Win32)\Output\Debug\cryptlib.lib
We will now use this file in the Windows Phone demo project.
Integrating Crypto++ with the Windows Phone C++ project
To make a new C++ project with Windows Phone 8, select File->New Project->Installed->Visual C++->Windows Phone ->Windows Phone Runtime Component:
Now copy the Cryptopp folder which contains the Cryptopp project you just compiled. Paste it to the location of the Windows Phone project:
Just as you set the project properties for the Cryptopp project, you need to set the properties for the Windows Phone C++ project:
- Configuration Properties->General->Platform Toolset - Windows Phone 8.0(v110)
- Configuration Properties->General->Configuration Type - Dynamic Library(.dll)
- Configuration Properties->C/C++->Code generation->Runtime library - Multi-threaded Debug (/MTd) for Debug Config & Multi-threaded DLL (/MD) for Release Config
- Configuration Properties->Linker->General->Additional Library Directories->path to lib folder under Microsoft SDK(e.g.: G:\Program Files %28x86%29\Microsoft SDKs\Windows\v7.1A\Lib\x64), for ARM this should be : G:\Program Files (x86)\Windows Kits\8.0\Lib\Win8\um\arm
- Configuration Properties->Linker->Input->Additional Dependencies -> path to previously compiled Cryptlib.lib (e.g. :\Documents\Visual Studio 2012\Projects\WindowsPhoneRuntimeComponent1\cryptopp28oct\Win32(or ARM)\Output\Release\cryptlib.lib
Recompile the project for both the Win32 & ARM platforms after performing above steps and the build should succeed.
Using Crypto++ classes
Now can use the Crypto++ classes and functions in your Windows Phone C++ project. Include the following headers and macros in your Windows Phone C++ project class:
#include "../cryptopp28oct/dll.h" // as Cryoptopp project folder is located inside the main Windows Phone C++ project folder
#include "../cryptopp28oct/default.h"
#ifdef CRYPTOPP_WIN32_AVAILABLE
#include <windows.h>
#endif
USING_NAMESPACE(CryptoPP)
USING_NAMESPACE(std)
using namespace WindowsPhoneRuntimeComponent1;
using namespace Platform;
using namespace Windows::Storage;
using namespace Windows::Foundation::Collections;
Crypto++ is a huge library that implements a number of cryptographic algorithms. The following example shows how to encrypt and decrypt a string.
//Encrypt
Platform::String^ WindowsPhoneRuntimeComponentEx::EncryptString(Platform::String^EncrytStr)
{
// convert the string to char* (as accepted by the C++ function from Crypto++)
Platform::String^ outstrtemp;
std::wstring fooW(EncrytStr->Begin());
std::string fooA(fooW.begin(), fooW.end());
const char* charStr = fooA.c_str(); // converted string
string outstr;
char*EncryKey = "12345";
DefaultEncryptorWithMAC encryptor(EncryKey, new HexEncoder(new StringSink(outstr)));
encryptor.Put((byte *)charStr , strlen(charStr));
encryptor.MessageEnd();
// convert the resulting C++ type string to a Windows Phone runtime style string
const char*iStr = outstr.c_str();
std::string s_str = std::string(iStr);
std::wstring wid_str = std::wstring(s_str.begin(), s_str.end());
const wchar_t* w_char = wid_str.c_str();
Platform::String^ p_string = ref new Platform::String(w_char);
return p_string ;
}
//Decrypt
Platform::String^ WindowsPhoneRuntimeComponentEx::DecryptString(Platform::String^EncryptdStr)
{
Platform::String^ outstrtemp;
string outstr;
std::wstring fooW(EncryptdStr->Begin());
std::string fooA(fooW.begin(), fooW.end());
const char* charStr = fooA.c_str();
HexDecoder decryptor(new DefaultDecryptorWithMAC("12345", new StringSink(outstr)));
decryptor.Put((byte *)charStr, strlen(charStr));
decryptor.MessageEnd();
// convert the resulting C++ type string to a Windows Phone runtime style string
const char*iStr = outstr.c_str();
std::string s_str = std::string(iStr);
std::wstring wid_str = std::wstring(s_str.begin(), s_str.end());
const wchar_t* w_char = wid_str.c_str();
Platform::String^ p_string = ref new Platform::String(w_char);
//const wchar_t* w_char = p_string->Data();
return p_string;
}
Header file:
...
public:
Platform::String^ EncryptString();
...
Linking Windows Phone C++ & Windows Phone C# project
The next step is to construct a user interface for the C++ project you created above. For example, you might do this to perform encryption/decryption on a button press.
To create a user interface, add a new Windows Phone (Visual C#) project to the Windows Phone C++ project you are using as follows:
- Choose File->New Project->Installed->Templates->Visual C#->Windows Phone ->Windows Phone App
- Add a reference to the Windows Phone C++ project (Windows Phone runtime) by right-clicking on the project and selecting Add Reference->Solution->path to Windows Phone C++(runtime) project.vcxproj
- Add two buttons: Encrypt and Decrypt, as well as a text box for an input string, to MainPage.xaml:
<StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" Margin="12,0"/>
<TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Margin="14,151,10,10" Grid.RowSpan="2">
<Button Content="Encrypt" HorizontalAlignment="Left" Margin="42,289,0,0" VerticalAlignment="Top" Click="Button_Click"/>
<TextBox HorizontalAlignment="Left" Name="TextBox1" Height="86" Margin="96,169,0,0" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="208"/>
<Button Content="Decrypt" HorizontalAlignment="Left" Margin="219,289,0,0" VerticalAlignment="Top" Click="Button_Click_1"/>
</Grid>
Write the implementation code for MainPage.xaml:
...
using Microsoft.Phone.Tasks;
using Windows.Storage;
using WindowsPhoneRuntimeComponent1; // c++ project name
public partial class MainPage : PhoneApplicationPage
{
...
string _encryptedStr;
//To encrypt a string
private void Button_Click(object sender, RoutedEventArgs e)
{
//Extlib
var Extlib = new WindowsPhoneRuntimeComponentEx();
_encryptedStr= Extlib.EncryptString(TextBox1.Text); /// calls the C++ function defined inside the Windows Phone Runtime project
TextBox1.Text = "";
MessageBox.Show(_encryptedStr);
MessageBox.Show(Extlib.EncryptString());
}
}
//To decrypt a string
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var Extlib = new WindowsPhoneRuntimeComponentEx();
MessageBox.Show(Extlib.DecryptString(_encryptedStr ))); // passes the encrypted string
}
License information
The compiled library is licensed under the Boost Software License 1.0 - for the full terms see the project License.txt. The project folder (Cryptopp) also contains a Readme.txt which includes all of the project build info as well as additional licensing information.
Example Project
An example project is attached. This project contains two projects:
- WindowsPhoneRuntimeComponent: This is the Windows Phone C++ project which connects with the Cryptlib.lib library and implements the functions responsible for encryption/decryption.
- LibTest : This is the Windows Phone C# App project that implements the user interface and interacts with the Windows Phone C++ project. In other words, the functions in the C++ project are called based on user interaction in LibTest.
The Crypto++ project involving Cryptlib that is responsible for the creation of .lib files, handles all of the encryption/decryption, and is linked with the Windows Phone C++ project is NOT attached. You should download it yourself from the Cryptopp home page and use it as described in the steps above.
External links
- How to encrypt data in a Windows Phone app
- System.Security.Cryptography Namespace
- Bouncy Castle for csharp
Notes
- ↑ Please read the Readme.txt document included inside cryptopp562 folder carefully to understand what each of four projects does and other relevant things
Contents
Txjule - can release lib file
i use the Microsoft Team Explorer for Visual Studio 2012 to release the cryptolib,but it was failed! i followed all you step! the error msg:
Error 9 error C2719: '_A': formal parameter with __declspec(align('16')) won't be aligned C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\xmmintrin.h 190txjule (talk) 10:28, 27 January 2014 (EET)
Vineet.jain - Yes that error appears
Hi Txjule,
The error you mentioned does actually comes up while compiling the project. Have you set the flags already as mentioned here :
http://developer.nokia.com/community/wiki/Using_Crypto%2B%2B_library_with_Windows_Phone_8#Resolving_problems_that_arise_while_building_the_library_project
Also the library project can be compiled with VS2012 for Desktop as well for VS2012 for Windows Phone.
Thanks
Vineetvineet.jain (talk) 12:02, 27 January 2014 (EET)
Ben.bader - "Compiling Desktop applications for the ARM platform is unsupported"
Hi Vineet,
First, thanks for the great article.
I'm wondering if you've encounted the above error? I'm compiling using VS 2013 on Windows 8.1; it appears that compiling static libs for ARM has been disabled. Do you know if it's possible to get around this and build crypto++? If so, how?
Thanks,
Benben.bader (talk) 06:58, 23 April 2014 (EEST)
Vineet.jain -
Hey Ben,
No i didn't faced any such error, there were errors pertaining to ARM thing but they were different as described in article. Though i was able to compile the project for VS2012 Express for desktop as well as for Windows Phone.
May be you could try this workaround : http://stackoverflow.com/questions/11151474/can-arm-desktop-programs-be-built-using-visual-studio-2012 , might work for VS2013 as well.
Thanks
Vineetvineet.jain (talk) 09:39, 23 April 2014 (EEST)
Diegostamigni -
Same problem here, can't compiling with Visual Studio 2013 (Update 2) for ARM.diegostamigni (talk) 00:12, 25 April 2014 (EEST)
Diegostamigni -
Seems that I've done: I've added the _ARM_WINAPI_PARTITION_DESKTOP_SDK_AVAILABLE preprocessor value for the ARM platform.diegostamigni (talk) 12:26, 25 April 2014 (EEST)
Vineet.jain - dedicated discussion group for Crypto++
There's also an dedicated discussion forum for Crypto++ library, probably you can ask the queries there as well: https://groups.google.com/forum/#!forum/cryptopp-usersvineet.jain (talk) 13:01, 30 April 2014 (EEST)