2008-12-11 17 views
10

में ऐसा लगता है कि सीबीसी-मैक एल्गोरिदम में 6 भिन्नताएं हैं। मैं पिनपैड 1000SE पर मैक एल्गोरिदम से मिलान करने की कोशिश कर रहा हूं [जो प्रति मैनुअल आईएसओ 9 7 9 7-1 एल्गोरिदम 1] है।आईएसओ 9 7797-1 एल्गोरिदम 1 [सीबीसी-मैक] सी #

मुझे here से उत्कृष्ट शुरुआत मिली।

और मैं नीचे के रूप में एल्गोरिथ्म कोडित:

public static byte[] CalculateMAC(this IPinPad pinpad, byte[] message, byte[] key) 
{ 
    //Divide the key with Key1[ first 64 bits] and key2 [last 64 bits] 
    var key1 = new byte[8]; 
    Array.Copy(key, 0, key1, 0, 8); 

    var key2 = new byte[8]; 
    Array.Copy(key, 8, key2, 0, 8); //64 bits 

    //divide the message into 8 bytes blocks 
    //pad the last block with "80" and "00","00","00" until it reaches 8 bytes 
    //if the message already can be divided by 8, then add 
    //another block "80 00 00 00 00 00 00 00" 
    Action<byte[], int> prepArray = (bArr, offset) => 
            { 
             bArr[offset] = 0; //80 
             for (var i = offset + 1; i < bArr.Length; i++) 
              bArr[i] = 0; 
            }; 
    var length = message.Length; 
    var mod = length > 8? length % 8: length - 8; 

    var newLength = length + ((mod < 0) ? -mod : (mod > 0) ? 8 - mod : 0); 
    //var newLength = length + ((mod < 0) ? -mod : (mod > 0) ? 8 - mod : 8); 
    Debug.Assert(newLength % 8 == 0); 

    var arr = new byte[newLength]; 
    Array.Copy(message, 0, arr, 0, length); 
    //Encoding.ASCII.GetBytes(message, 0, length, arr, 0); 
    prepArray(arr, length); 
    //use initial vector {0,0,0,0,0,0,0,0} 
    var vector = new byte[] { 0, 0, 0, 0, 0, 0, 0, 0 }; 

    //encrypt by DES CBC algorith with the first key KEY 1 
    var des = new DESCryptoServiceProvider { Mode = CipherMode.CBC }; 
    var cryptor = des.CreateEncryptor(key1, vector); 
    var outputBuffer = new byte[arr.Length]; 
    cryptor.TransformBlock(arr, 0, arr.Length, outputBuffer, 0); 

    //Decrypt the result by DES ECB with the second key KEY2 [Original suggestion] 
    //Now I'm Encrypting 
    var decOutputBuffer = new byte[outputBuffer.Length]; 
    des.Mode = CipherMode.ECB; 
    var decryptor = des.CreateEncryptor(key2, vector); 
    //var decryptor = des.CreateDecryptor(key2, vector); 
    decryptor.TransformBlock(outputBuffer, 0, outputBuffer.Length, decOutputBuffer, 0); 

    //Encrypt the result by DES ECB with the first key KEY1 
    var finalOutputBuffer = new byte[decOutputBuffer.Length]; 
    var cryptor2 = des.CreateEncryptor(key1, vector); 
    cryptor2.TransformBlock(decOutputBuffer, 0, decOutputBuffer.Length, finalOutputBuffer, 0); 

    //take the first 4 bytes as the MAC 
    var rval = new byte[4]; 
    Array.Copy(finalOutputBuffer, 0, rval, 0, 4); 
    return rval; 
} 

तब मुझे पता चला वहाँ हो 3 गद्दी योजनाओं और एक है कि मुझे एक शुरुआत दे दी है जरूरी नहीं कि सही हो सकता है। मैनुअल फिर से मेरे बचाव के लिए आया था। ऐसा लगता है कि डिवाइस केवल 0 के साथ पैड है। अतिरिक्त ब्लॉक भी कहीं नहीं तो उल्लेख किया है मैं नीचे परिवर्तन किए:

Action<byte[], int> prepArray = (bArr, offset) => 
            { 
             bArr[offset] = 0; ... } 

कोई अतिरिक्त ब्लॉक

var newLength = length + ((mod < 0) ? -mod : (mod > 0) ? 8 - mod : 0); 

(यदि आधुनिक 0 [8 से विभाज्य] सरणी लंबाई को बदल नहीं है) मूल सुझाव मुझे चाहता था दूसरे चरण पर डिक्रिप्ट करने के लिए ... लेकिन वैलेरी here बताता है कि यह सभी तरह से एन्क्रिप्ट किया गया है। तो मैंने डिक्रिप्ट को एन्क्रिप्ट करने के लिए बदल दिया। लेकिन फिर भी मैं अपेक्षित मैक प्राप्त करने में असमर्थ हूँ ...

मैन्युअल कुंजी "6AC292FAA1315B4D8234B3A3D7D5933A" के लिए कहते हैं [के बाद से प्रमुख 16 बाइट्स होना चाहिए, मैं समझ कुंजी यहाँ हेक्स स्ट्रिंग है तो मैं 6A, सी 2 की बाइट मूल्यों ले लिया , 9 2, एफए ... नया बाइट [] {106, 1 9 4, 146, ...] मैक 7 बी, 40, बीए, 9 5 [4 बाइट्स] होना चाहिए यदि संदेश है [MENTERODOMETER का 0x1a + बाइट सरणी]

क्या कोई मदद कर सकता है? कृप्या?


के बाद से PINPAD की आवश्यकता है कि संदेश में पहले वर्ण एक 0x1A है ...

public static byte[] CalculateAugmentedMAC(this IPinPad pinpad, string message, byte[] key) 
{ 
    var arr = new byte[message.Length + 1]; 
    var source = Encoding.ASCII.GetBytes(message); 
    arr[0] = 0x1a; //ClearScreenIndicator 
    Array.Copy(source, 0, arr, 1, source.Length); 
    return CalculateMAC(pinpad, arr, key); 
} 

मैं इस इनपुट के साथ उपरोक्त कोड फोन कर रहा हूँ:

var result = pad.CalculateAugmentedMAC("MENTERODOMETER", new byte[] { 106, 194, 146, 250, 161, 49, 91, 77, 130, 52, 179, 163, 215, 213, 147, 58 }); 
+2

उत्सुक। पिनपैड डेटा को एन/डिक्रिप्ट करने में आपको शामिल होने की आवश्यकता क्यों होगी? पिनपैड वर्कफ़्लो बैंक द्वारा उत्पन्न डीयूकेपीटी कुंजी का उपयोग करके सीधे व्यापारी के बैंक को एन्क्रिप्टेड डेटा भेजने के लिए डिज़ाइन किया गया है और पिनपैड विक्रेता द्वारा पिनपैड में स्थापित किया गया है। यहां तक ​​कि उस बिंदु तक पहुंचना जहां हम विभिन्न पिनपैड के यूआई और अन्य व्यवहार को सीधे नियंत्रित करने के लिए सॉफ्टवेयर लिख रहे थे, हम प्रक्रिया के हिस्से के रूप में प्रदान किए गए एन्क्रिप्टेड पिन डेटा लिफाफे को एन्क्रिप्ट/डिक्रिप्ट करने की आवश्यकता नहीं थी। – Bill

+0

विधेयक, आप सही हैं ... लेकिन अगर आप एक वफादारी प्रबंधन आवेदन लिखना चाहते थे जो संरक्षक को पिन की अनुमति देता है, तो आपको इन प्री-प्रोग्रामेड कुंजी के बिना इसका उपयोग करने की आवश्यकता है .... पिनपैड 1000SE का पहला मॉडल - याद नहीं कर सकता मेरे सिर के शीर्ष पर - आपको पिन प्राप्त करने और स्पष्ट टेक्स्ट के रूप में भेजने की अनुमति दी गई थी। बाद के मॉडल पिन एन्क्रिप्ट करते हैं और हम इसे प्राप्त नहीं कर सकते ... –

उत्तर

2

अधिकांश सीबीसी मैक एल्गोरिदम BouncyCastle के जेसीई प्रदाता में लागू किए गए हैं।

देखो पर: BouncyCastleProvider.java

आप शायद DESEDEISO9797ALG1MACWITHISO7816-4PADDING लिए देख रहे हैं, जो DESEDEMAC64WITHISO7816-4PADDING के लिए एक उपनाम है, यहाँ लागू किया (अच्छी तरह से, यह CBCBlockCipherMac की एक विशिष्ट विन्यास DESedeEngine और ISO7816d4Padding का उपयोग कर रहा है, तो आप कूद करना होगा इसके अलावा JCEMac.java

, jPos पर एक नजर है: कुछ वर्गों के बीच पूरी तस्वीर प्राप्त करने के लिए)

JCESecurityModule.java

और उनके योगदान खुदरा मैक एल्गोरिथ्म कार्यान्वयन:

retail-mac-contributed-by-vsalaman.zip

0

मैं यकीन है कि (IIRC) है कि आप अंत (encryptor प्रति) पर TransformFinalBlock कॉल करने की आवश्यकता है।

0

आपके विशिष्ट टर्मिनल का उत्तर नहीं दे सकता है, लेकिन मै मैक का परीक्षण करने के लिए इसका उपयोग करता हूं।

public static byte[] GenerateMAC(byte[] key, byte[] data) 
{ 
    using (MACTripleDES mac = new MACTripleDES(key)) 
     return mac.ComputeHash(data); 
} 
संबंधित मुद्दे