PHP: How to distinguish between encrypted and unencrypted email? - php

I want to create a new email account which only receives encrypted email. Unfortunately, I cannot modify the mail server configuration so I considered checking incoming email every 2 minutes with a cronjob and automatically rejecting those messages which are not encrypted.
So far I did this:
$body = imap_body($mbox, $i);
if (substr($body,0,27) == "-----BEGIN PGP MESSAGE-----")
$encrypted = true;
else
$encrypted = false;
Works, but I'm pretty sure I don't capture all encrypted email. I didn't find a unique option in the header which would tell me that a message is encrypted. Enigmail left a message though:
X-Enigmail-Version: 1.5.1
This, however, does not help me in any way. Is it enough to just grep for the BEGIN PGP MESSAGE string as I did above?

As a student of computational linguistics my first idea was to try it statistically:
As far as I know encrypted messages do not contain spaces. So you could tokenize the email body into words, and calculate the average length of the words. Try this on some other mails or texts and see how the average length differs.
It may be a bit extravagant, but is more effective than looking for a substring: for example someone may send a webpage or text dealing with encryption or the latest NSA leaks ;-)

Related

LibSodium functions return unreadable characters

I am following along with a tutorial on encryption: https://php.watch/articles/modern-php-encryption-decryption-sodium. In working with the Sodium extension I'm just baffled by a few things. Googling is returning frustratingly little help. (Most of the results are just duplications of the php.net/manual.)
1. In various articles I'm reading, the result of sodium_crypto_*_encrypt() is something familiar:
// ex. DEx9ATXEg/eRq8GWD3NT5BatB3m31WED
Whenever I echo it out myself I get something like:
// ex. 𫦢�2(*���3�CV��Wu��R~�u���H��
which I'm certain won't store correctly on a database. Nowhere in the articles or documentation does it mention anything about charset weirdness. I can throw a header('Content-Type: text/html; charset=ISO-8859-1') in there, but I still get weird characters I'm not certain are right since I'm not finding any threads talking about this:
// ex. ÑAÁ5eŠ…n#±'ýÞÃ1è9ÜÈ̳¬"CžãÚ0ÿÛ
2. I can't find any information about the best practice for storing keys or nonces.
I just figured this obvious-to-security-folks-but-not-to-others bit of information would be a regularly discussed part of articles on keygens and nonces and such. Seeing as both my keygen and nonce functions (at least in the Sodium library) seem to return non-UTF-8 gibberish, what do I do with it? fwrite it out to a file to be referenced later? Pass it directly to my database? Copy/pasting certainly doesn't work right with it being wingdings.
Other than these things, everything else in the encryption/decryption process makes complete sense to me. I'm far from new to PHP development, I just can't figure this out.
Came across https://stackoverflow.com/a/44874239/1128978 answering "PHP random_bytes returns unreadable characters"
random_bytes generates an arbitrary length string of cryptographic random bytes...
And suggests to use bin2hex to get readable characters. So amending my usages:
// Generate $ciphertext
$message = 'This is a secret message';
$key = sodium_crypto_*_keygen();
$nonce = random_bytes(SODIUM_CRYPTO_*BYTES);
$ciphertext = sodium_crypto_*_encrypt($message, '', $nonce, $key);
// Store hexadecimal versions of binary output
$nonce_hex = bin2hex($nonce);
$key_hex = bin2hex($key);
$ciphertext_hex = bin2hex($ciphertext);
// When ready to decrypt, convert hexadecimal values back to binary
$ciphertext_bin = hex2bin($ciphertext_hex);
$nonce_bin = hex2bin($nonce_hex);
$key_bin = hex2bin($key_hex);
$decrypted = sodium_crypto_*_decrypt($ciphertext_bin, '', $nonce_bin, $key_bin);
// "This is a secret message"
So making lots of use of bin2hex and hex2bin, but this now makes sense. Effectively solved, though not confident this is the proper way to work with it. I still have no idea why this isn't pointed out anywhere in php.net/manual nor in any of the articles/comments I've been perusing.

PHP iOS Push notifications arabic multilingual text larger in size

I don't really know how to ask these but hopefully i can make myself clear enough for you to understand my questions
Below is the Arabic text which I want to send via Apple iPhone Push Notifications:
يبدا بقرص العقيلي واللقيمات وينتهي مع خالد حرية بالامارات نكهة وبهار مع القصار-٦ مساءا على يشان الليله في انا والعسل مع غاده عبدالرازق تلفزيون الكويت
Can i send this long text?
Because when I prepare a payload, it says 360 bytes of size. While Apple allows only 256 bytes of payload.
What can be done for same?
I'm using this code for same.
Doesn't sound like this is something you can work around. Try shortening the notification message and then pointing the user towards your app where you can display a more descriptive message.
Got one trick [not sure this is permanent soln though] temporarily: May be handy to other people in future
commented below code of line
//$payload = json_encode($body);
And directly appending JSON format to Payload variable
$payload = '{"aps":{"alert":"'.$message.'","sound":"default","badge":"+1"}}';
Here, $message will be my Arabic string for actula message and it WORKS !!

PHP encrypt - and decrypt otherthan base64 encode

In one of our web application ( in PHP, MySQL ) we are saving user's mobile number as encrypted value and decrypt it when we send SMS to them. The application was pretty working well. But
now GoDaddy removed the option base64_encode and decode. So that we cant send SMS to users. So we revert back the mobile numbers to its normal state running it locally.
My question is which is the easiest and safe way to encrypt and decrypt a string using a key.
Something like
Normal string : 9876543210 -> After encrypt with a key -> AASASOOPFPOEROP45664654456
Encrypted string : AASASOOPFPOEROP45664654456 -> on decrypt -> 9876543210
My current code
function encodeString($str){
for($i=0; $i<5;$i++)
{
$str=strrev(base64_encode($str)); //apply base64 first and then reverse the string
}
return $str;
}
function decodeString($str){
for($i=0; $i<5;$i++)
{
$str=base64_decode(strrev($str)); //apply base64 first and then reverse the string}
}
return $str;
}
Please help me . Thanks in advance
Well if you were using base64 encode/decode you weren't encrypting the data, just obfuscating.
I don't know what php extensions godaddy has enabled, so I would suggest going with something like phpSecLib
http://phpseclib.sourceforge.net/
It is a standalone implementation you can include into your scripts, and will provide actual encryption of your data. AES or Rijndael should work find for your application
Basically it will encrypt the string with a key, even if your database is compromised, the data can't be decrypted without the key it was encrypted with (which you would hard coded into your script). This is unlike simply encoding it, in which case if someone got ahold of the database, they could decode it by running the first string through a variety of different encoding methods until they find one that works. And then run the rest through the same decoding method
here i am giving you one simple example with our own secret key you can use as below
// Secret key to encrypt/decrypt with
$key='mysecretkey'; // 8-32 characters without spaces
// String to encrypt
$string1='your sample key, that is the question';
// EnCrypt string
$string2=convert($string1,$key);
// DeCrypt back
$string3=convert($string2,$key);
// Test output
echo '<span style="font-family:Courier">';
echo 'Key: '.$key.'<br>'."\n";
echo $string1.'<br>'."\n";
echo $string2.'<br>'."\n";
echo $string3.'<br>'."\n";
echo '</span>'."\n";
OUTPUT
Key: mysecretkey
your sample key, that is the question
tvfw#ady{i|-rv|/2q|jq9dj3qkw%e~`jyp|k
your sample key, that is the question
Let me know i can help you more.

How to encrypt a string in Python and decrypt that same string in PHP?

I have a string that I would like to encrypt in Python, store it as a cookie, then in a PHP file I'd like to retrieve that cookie, and decrypt it in PHP. How would I go about doing this?
I appreciate the fast responses.
All cookie talk aside, lets just say I want to encrypt a string in Python and then decrypt a string in PHP.
Are there any examples you can point me to?
Use a standard encryption scheme. The implementation is going to be equivalent in either language.
RSA is available (via third party libraries) in both languages, if you need asymmetric key crypto. So is AES, if you need symmetric keys.
There is a good example here:
http://www.codekoala.com/blog/2009/aes-encryption-python-using-pycrypto/
Other links that may help:
http://www.phpclasses.org/browse/package/4238.html
http://www.chilkatsoft.com/p/php_aes.asp
If you're not talking about encryption but encoding to make sure the contents make it through safely regardless of quoting issues, special characters, and line breaks, I think base64 encoding is your best bet. PHP has base64_encode / decode() out of the box, and I'm sure Python has, too.
Note that base64 encoding obviously does nothing to encrypt your data (i.e. to make it unreadable to outsiders), and base64 encoded data grows by 33%.
Well, my first thought would be to use a web server that uses SSL and set the cookie's secure property to true, meaning that it will only be served over SSL connections.
However, I'm aware that this probably isn't what you're looking for.
Although a bit late. Find sample code below using the Fernet library
#Python Code - fernet 1.0 library
from cryptography.fernet import Fernet
key = b"Gm3wFh9OiQHcVc8rcAMm8IOqKOJtk7CbrGRKVhrvXhg="
f = Fernet(key)
token = f.encrypt(b'the quick brown fox jumps over the lazy hare')
print(token)
##gAAAAABiMWVPsStLo42ExcmIqcGvRvCCmnhB5B6dc2JsOm4w-VsE9oJOuk_qYuZvHv5quQR4t_6ZjNJzAdCiDPOtESNzCreJZLwc2X-_apbqKKnBwc3KhmqL-K5X7t1uR1WXuyUEYUtW
<?php
//PHP - kelvinmo/fernet-php v1.0.1 A
require 'vendor/autoload.php';
use Fernet\Fernet;
$key = "Gm3wFh9OiQHcVc8rcAMm8IOqKOJtk7CbrGRKVhrvXhg=" ;
$fernet = new Fernet($key);
$token = "gAAAAABiMWVPsStLo42ExcmIqcGvRvCCmnhB5B6dc2JsOm4w-VsE9oJOuk_qYuZvHv5quQR4t_6ZjNJzAdCiDPOtESNzCreJZLwc2X-_apbqKKnBwc3KhmqL-K5X7t1uR1WXuyUEYUtW";
echo $fernet->decode($token);
?>

in php how to find already encrypted file in specific folder

I am using PGP (GNU Privacy Guard) for encrypting the file.
while encrypting i removed the '.pgp' extension of encrypted file.
Now some how i want to know which file is already encrypted in the specific folder.
Note :- my goal is that ... do not encrypt any file twice ... so before encrypt any file .. i want to check is the file already encrypted.
in php can we find out which file is already encrypted ?
PGP file all starts with "-----BEGIN PGP MESSAGE-----".
So you can do something like this:
$content = file_get_contents($filename);
$encrypted = strpos($content, '-----BEGIN PGP MESSAGE-----') === 0;
I really don't know much about how it works, or how you could look at the contents of the file to tell if it is encrypted properly, but could you try decrypting them? If you know you're only working with plain text files, you could examine the first 500 bytes of the decrypted data and if there's strange characters (outside the standard a-z A-Z 0-9 + punctuation, etc), then that could be a clue that the file wasn't encrypted.
This really is a half-arsed answer, I know, but it was a bit long to fit into a comment.
You can't unless you understand the algorithm used in the encryption. Once you understand it, you can apply that to check whether a file is already encrypted.
Also check to make sure that there is already a function available in PGP for checking if something is already encrypted. This is usually present in encryption solutions.
Thanks
There are two possible formats for OpenPGP data, binary and ascii armored.
Ascii-armored files are easy to recognize by looking for "-----BEGIN PGP MESSAGE-----" which can also be done using the unix command file:
$ file encrypted
encrypted: PGP message
#ZZ_Coders answer is totally fine if you're only dealing with ascii armored encrypted files.
If it shows something else, it's not an OpenPGP message - or in binary format. This isn't as easy to recognize (at least I don't know which magic packets you could look for), but you can easily use the gpg command to test the file:
$ gpg --list-only --list-packets encrypted
:pubkey enc packet: version 3, algo 1, keyid DEAFBEEFDEADBEEF
data: [2048 bits]
:encrypted data packet:
length: 73
mdc_method: 2
If it isn't encrypted, response will look like this:
$ gpg --list-only --list-packets something_else
gpg: no valid OpenPGP data found.
In PHP, you could use this code to check if a file is OpenPGP-encrypted:
if (strpos(`gpg --list-only --list-packets my_file.txt 2>&1`,
'encrypted data packet'))
echo "encrypted file";

Categories